teiid SVN: r3317 - in trunk: api/src/main/java/org/teiid/language/visitor and 33 other directories.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2011-07-19 23:27:02 -0400 (Tue, 19 Jul 2011)
New Revision: 3317
Added:
trunk/engine/src/main/java/org/teiid/query/sql/symbol/WindowFunction.java
Removed:
trunk/engine/src/main/java/org/teiid/core/id/IntegerID.java
trunk/engine/src/main/java/org/teiid/core/id/IntegerIDFactory.java
trunk/engine/src/main/java/org/teiid/core/id/InvalidIDException.java
trunk/engine/src/main/java/org/teiid/core/id/LongID.java
trunk/engine/src/main/java/org/teiid/core/id/LongIDFactory.java
trunk/engine/src/main/java/org/teiid/core/id/ObjectID.java
trunk/engine/src/main/java/org/teiid/core/id/ObjectIDFactory.java
trunk/engine/src/main/java/org/teiid/core/id/ParsedObjectID.java
trunk/engine/src/main/java/org/teiid/core/id/StringID.java
trunk/engine/src/main/java/org/teiid/core/id/StringIDFactory.java
trunk/engine/src/main/java/org/teiid/core/id/UUIDFactory.java
trunk/engine/src/test/java/org/teiid/core/id/
Modified:
trunk/api/src/main/java/org/teiid/language/AggregateFunction.java
trunk/api/src/main/java/org/teiid/language/visitor/HierarchyVisitor.java
trunk/api/src/main/java/org/teiid/language/visitor/SQLStringVisitor.java
trunk/api/src/main/java/org/teiid/translator/ExecutionFactory.java
trunk/documentation/reference/src/main/docbook/en-US/content/sql_support.xml
trunk/engine/src/main/java/org/teiid/core/id/IDGenerator.java
trunk/engine/src/main/java/org/teiid/core/id/UUID.java
trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/CapabilitiesConverter.java
trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/LanguageBridgeFactory.java
trunk/engine/src/main/java/org/teiid/dqp/internal/process/Request.java
trunk/engine/src/main/java/org/teiid/query/optimizer/BatchedUpdatePlanner.java
trunk/engine/src/main/java/org/teiid/query/optimizer/QueryOptimizer.java
trunk/engine/src/main/java/org/teiid/query/optimizer/capabilities/SourceCapabilities.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/PlanToProcessConverter.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/FrameUtil.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/NewCalculateCostUtil.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleAssignOutputElements.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleChooseJoinStrategy.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleCollapseSource.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleConstants.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleDecomposeJoin.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleMergeCriteria.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/RulePlaceAccess.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RulePlanSorts.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RulePushAggregates.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RulePushSelectCriteria.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleRaiseAccess.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleRaiseNull.java
trunk/engine/src/main/java/org/teiid/query/parser/ParseInfo.java
trunk/engine/src/main/java/org/teiid/query/processor/relational/DependentCriteriaProcessor.java
trunk/engine/src/main/java/org/teiid/query/processor/relational/GroupingNode.java
trunk/engine/src/main/java/org/teiid/query/processor/relational/SortUtility.java
trunk/engine/src/main/java/org/teiid/query/resolver/util/ResolverUtil.java
trunk/engine/src/main/java/org/teiid/query/resolver/util/ResolverVisitor.java
trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
trunk/engine/src/main/java/org/teiid/query/sql/LanguageVisitor.java
trunk/engine/src/main/java/org/teiid/query/sql/lang/GroupBy.java
trunk/engine/src/main/java/org/teiid/query/sql/navigator/PreOrPostOrderNavigator.java
trunk/engine/src/main/java/org/teiid/query/sql/symbol/AggregateSymbol.java
trunk/engine/src/main/java/org/teiid/query/sql/symbol/AliasSymbol.java
trunk/engine/src/main/java/org/teiid/query/sql/symbol/ElementSymbol.java
trunk/engine/src/main/java/org/teiid/query/sql/symbol/ExpressionSymbol.java
trunk/engine/src/main/java/org/teiid/query/sql/visitor/AggregateSymbolCollectorVisitor.java
trunk/engine/src/main/java/org/teiid/query/sql/visitor/ElementCollectorVisitor.java
trunk/engine/src/main/java/org/teiid/query/sql/visitor/ExpressionMappingVisitor.java
trunk/engine/src/main/java/org/teiid/query/sql/visitor/GroupsUsedByElementsVisitor.java
trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java
trunk/engine/src/main/java/org/teiid/query/util/CommandContext.java
trunk/engine/src/main/java/org/teiid/query/validator/AggregateValidationVisitor.java
trunk/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java
trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj
trunk/engine/src/main/resources/org/teiid/query/i18n.properties
trunk/engine/src/test/java/org/teiid/dqp/internal/process/multisource/TestMultiSourcePlanToProcessConverter.java
trunk/engine/src/test/java/org/teiid/query/optimizer/TestAggregatePushdown.java
trunk/engine/src/test/java/org/teiid/query/optimizer/TestExpressionsInGroupBy.java
trunk/engine/src/test/java/org/teiid/query/optimizer/TestInlineView.java
trunk/engine/src/test/java/org/teiid/query/optimizer/TestLimit.java
trunk/engine/src/test/java/org/teiid/query/optimizer/TestOptimizer.java
trunk/engine/src/test/java/org/teiid/query/optimizer/xml/TestXMLPlanner.java
trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java
trunk/engine/src/test/java/org/teiid/query/processor/TestAggregateProcessing.java
trunk/engine/src/test/java/org/teiid/query/processor/TestProcessor.java
trunk/engine/src/test/java/org/teiid/query/processor/TestVirtualDepJoin.java
trunk/engine/src/test/java/org/teiid/query/sql/symbol/TestSearchedCaseExpression.java
trunk/engine/src/test/java/org/teiid/query/sql/visitor/TestExpressionMappingVisitor.java
trunk/engine/src/test/java/org/teiid/query/validator/TestValidator.java
trunk/test-integration/common/src/test/java/org/teiid/dqp/internal/process/TestTPCR.java
Log:
TEIID-1676 TEIID-1667 changing base aggregate planning to use an symbolic planning form. beginnings of window function support. fix for cardinality dependent aggregate decomposition
Modified: trunk/api/src/main/java/org/teiid/language/AggregateFunction.java
===================================================================
--- trunk/api/src/main/java/org/teiid/language/AggregateFunction.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/api/src/main/java/org/teiid/language/AggregateFunction.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -43,6 +43,7 @@
private String aggName;
private boolean isDistinct;
private Class<?> type;
+ private Expression condition;
public AggregateFunction(String aggName, boolean isDistinct, Expression exp, Class<?> type) {
this.expression = exp;
@@ -118,5 +119,17 @@
public void setType(Class<?> type) {
this.type = type;
}
+
+ /**
+ *
+ * @return the filter clause condition
+ */
+ public Expression getCondition() {
+ return condition;
+ }
+
+ public void setCondition(Expression condition) {
+ this.condition = condition;
+ }
}
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-19 13:41:13 UTC (rev 3316)
+++ trunk/api/src/main/java/org/teiid/language/visitor/HierarchyVisitor.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -79,6 +79,7 @@
public void visit(AggregateFunction obj) {
visitNode(obj.getExpression());
+ visitNode(obj.getCondition());
}
public void visit(BatchedUpdates obj) {
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-19 13:41:13 UTC (rev 3316)
+++ trunk/api/src/main/java/org/teiid/language/visitor/SQLStringVisitor.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -60,6 +60,7 @@
import org.teiid.language.Not;
import org.teiid.language.OrderBy;
import org.teiid.language.QueryExpression;
+import org.teiid.language.SQLConstants;
import org.teiid.language.ScalarSubquery;
import org.teiid.language.SearchedCase;
import org.teiid.language.SearchedWhenClause;
@@ -174,11 +175,22 @@
}
if (obj.getExpression() == null) {
- buffer.append(Tokens.ALL_COLS);
+ if (SQLConstants.NonReserved.COUNT.equalsIgnoreCase(obj.getName())) {
+ buffer.append(Tokens.ALL_COLS);
+ }
} else {
append(obj.getExpression());
}
buffer.append(Tokens.RPAREN);
+ if (obj.getCondition() != null) {
+ buffer.append(Tokens.SPACE);
+ buffer.append(FILTER);
+ buffer.append(Tokens.LPAREN);
+ buffer.append(WHERE);
+ buffer.append(Tokens.SPACE);
+ append(obj.getCondition());
+ buffer.append(Tokens.RPAREN);
+ }
}
public void visit(Comparison obj) {
Modified: trunk/api/src/main/java/org/teiid/translator/ExecutionFactory.java
===================================================================
--- trunk/api/src/main/java/org/teiid/translator/ExecutionFactory.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/api/src/main/java/org/teiid/translator/ExecutionFactory.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -860,5 +860,31 @@
public boolean supportsCommonTableExpressions() {
return false;
}
+
+ /**
+ * @return true if Advanced OLAP operations are supporting
+ * including the aggregate function filter clause.
+ * @since 7.5
+ */
+ public boolean supportsAdvancedOlapOperations() {
+ return false;
+ }
+
+ /**
+ * @return true if Elementary OLAP operations are supporting
+ * including window functions
+ * @since 7.5
+ */
+ public boolean supportsElementaryOlapOperations() {
+ return false;
+ }
+
+ /**
+ * @return true if array_agg is supported
+ * @since 7.5
+ */
+ public boolean supportsArrayAgg() {
+ return false;
+ }
}
Modified: trunk/documentation/reference/src/main/docbook/en-US/content/sql_support.xml
===================================================================
--- trunk/documentation/reference/src/main/docbook/en-US/content/sql_support.xml 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/documentation/reference/src/main/docbook/en-US/content/sql_support.xml 2011-07-20 03:27:02 UTC (rev 3317)
@@ -264,13 +264,22 @@
</para>
</listitem>
<listitem>
- <para>Aggregate functions may only be used in the HAVING or SELECT clauses and may not be nested within another aggregate function.
+ <para>Aggregate functions cannot be used in FROM, GROUP BY, or WHERE clauses without an intervening query expression.
</para>
</listitem>
<listitem>
+ <para>Aggregate functions cannot be nested within another aggregate function without an intervening query expression.
+ </para>
+ </listitem>
+ <listitem>
<para>Aggregate functions may be nested inside other functions.
</para>
</listitem>
+ <listitem>
+ <para>Any aggregate function may take an optional FILTER clasue of the form <synopsis label="Usage">FILTER ( WHERE condition )</synopsis>. The condition may be any boolean value expression that does not contain a subquery or a correlated variable.
+ The filter will logically be evaluated for each row prior to the grouping operation. If false the aggregate function will not accumulate a value for the given row.
+ </para>
+ </listitem>
</itemizedlist>
<para>
For more information on aggregates, see the sections on GROUP BY or HAVING.
Modified: trunk/engine/src/main/java/org/teiid/core/id/IDGenerator.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/core/id/IDGenerator.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/core/id/IDGenerator.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -22,306 +22,17 @@
package org.teiid.core.id;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import org.teiid.core.CorePlugin;
-
-
/**
* IDGenerator
*/
public class IDGenerator {
- private static final IDGenerator INSTANCE = new IDGenerator();
-
- /**
- * Obtain the shared instance of this class.
- * @return the statically shared instance of this class.
- */
- public static IDGenerator getInstance() {
- return INSTANCE;
- }
-
- /** ObjectIDFactory instances keyed by protocol */
- private final Map factories;
- private final Set protocols;
+ private int id;
+
+ public int nextInt() {
+ return id++;
+ }
- private ObjectIDFactory defaultFactory;
-
- public IDGenerator() {
- this.factories = new HashMap();
- this.protocols = new HashSet();
-
- // Initialize default factory ...
- final ObjectIDFactory newDefaultFactory = new UUIDFactory();
- addFactory( newDefaultFactory );
- if ( !this.hasDefaultFactory() ) {
- this.setDefaultFactory(newDefaultFactory);
- }
- }
-
- /**
- * Method that creates and adds to this generator all the built-in factories, and if there is no default
- * factory, set the default factory to the {@link UUIDFactory}.
- * This method may be called multiple times without side effect.
- */
- public void addBuiltInFactories() {
- // Add the UUID factory as the default ...
- final ObjectIDFactory newDefaultFactory = new UUIDFactory();
- addFactory( newDefaultFactory );
- if ( !this.hasDefaultFactory() ) {
- this.setDefaultFactory(newDefaultFactory);
- }
- addFactory( new IntegerIDFactory() );
- addFactory( new LongIDFactory() );
- addFactory( new StringIDFactory() );
- }
-
- /**
- * Supply to this generator a new factory for a type of {@link ObjectID}.
- * This method has no effect if the factory is null, or if this generator already knows
- * about the factory.
- * @param factory the new factory
- */
- public void addFactory( final ObjectIDFactory factory ) {
- if ( factory == null ) {
- return;
- }
- final String protocol = factory.getProtocol();
-
- // See if the factory is already known ...
- if ( !this.factories.containsKey(protocol) ) {
- this.factories.put(protocol,factory);
- }
- this.protocols.add(protocol);
- }
-
- /**
- * Remove a factory from this generator.
- * This method has no effect if the supplied protocol doesn't match the protocol of any descriptor
- * known to this generator.
- * @param protocol the protocol for which the factory is to be removed
- * @return whether a factory was found and removed for the supplied protocol
- */
- public boolean removeFactory(String protocol) {
- if ( protocol == null ) {
- return false;
- }
- final Object previous = this.factories.remove(protocol);
- if ( previous != null ) {
- this.protocols.remove(protocol);
- return true;
- }
- return false;
- }
-
- /**
- * Method to obtain the collection of {@link ObjectIDFactory} instances that each describe
- * one of the types of {@link ObjectID}s that are available to this generator.
- * @return the collection of {@link ObjectIDFactory} instances.
- */
- public Collection getFactories() {
- // Currently, we get the collection of values from the 'factories' map. This is okay,
- // because although not terribly efficient, this method is not intended to be called very
- // frequently
- return factories.values();
- }
-
- /**
- * Method to obtain the collection of {@link ObjectIDFactory} instances that each describe
- * one of the types of {@link ObjectID}s that are available to this generator.
- * @return the collection of {@link ObjectIDFactory} instances.
- */
- public ObjectIDFactory getFactory( final String protocol ) {
- return (ObjectIDFactory) this.factories.get(protocol);
- }
-
- /**
- * Method to obtain the set of {@link java.lang.String String} protocols. This is a utility that merely obtains the
- * protocols from the factories.
- * @return the Set of String protocols; never null
- */
- public Set getProtocols() {
- return factories.keySet();
- }
-
- /**
- * Return whether there is a factory that is used by default for the {@link #create()} method is invoked.
- * @return true if there is a default factory, or false otherwise
- */
- public boolean hasDefaultFactory() {
- return defaultFactory != null;
- }
-
- /**
- * Get the factory that is used by default for the {@link #create()} method is invoked.
- * @return the default factory, or null if there is no default factory
- */
- public ObjectIDFactory getDefaultFactory() {
- return defaultFactory;
- }
-
- /**
- * Set the factory that should be used by default for the {@link #create()} method is invoked.
- * @param factory the factory that should be used by default; may be null if no default is to be allowed.
- */
- public void setDefaultFactory(final ObjectIDFactory factory) {
- defaultFactory = factory;
- }
-
- /**
- * Set the factory that should be used by default for the {@link #create()} method is invoked.
- * @param protocol the protocol for factory that should be used by default; may be null if no default
- * is to be allowed.
- */
- public void setDefaultFactory(final String protocol) {
- final ObjectIDFactory factory = getFactory(protocol); // null if protocol doesn't match
- defaultFactory = factory;
- }
-
- /**
- * Create a new {@link ObjectID} using the default factory
- * @return the new ObjectID
- */
- public ObjectID create() {
- if ( this.defaultFactory != null ) {
- return this.defaultFactory.create();
- }
- // Invalid protocol
- throw new IllegalArgumentException(CorePlugin.Util.getString("IDGenerator.No_default_id_factory_has_been_defined")); //$NON-NLS-1$
- }
-
- /**
- * Create a new {@link ObjectID} for the type specified by the protocol
- * @param protocol the protocol of the type of {@link ObjectID} to be created; may not be null
- * @return the new ObjectID
- */
- public ObjectID create( final String protocol ) {
- if (protocol == null) {
- final String msg = CorePlugin.Util.getString("IDGenerator.The_protocol_may_not_be_null"); //$NON-NLS-1$
- throw new IllegalArgumentException(msg);
- }
- // Get the factory ...
- final ObjectIDFactory factory = (ObjectIDFactory) this.factories.get(protocol);
- if ( factory != null ) {
- // Create the new ObjectID ...
- return factory.create();
- }
- // Invalid protocol
- throw new IllegalArgumentException(CorePlugin.Util.getString("IDGenerator.The_specified_ObjectID_protocol___8",protocol)); //$NON-NLS-1$
- }
-
- /**
- * Convenience method for obtaining the stringified form of an ObjectID.
- * @param id
- * @return
- */
- public String toString( final ObjectID id ) {
- return id.toString();
- }
-
- /**
- * Convenience method for obtaining the stringified form of an ObjectID.
- * @param id
- * @return
- */
- public String toString( final ObjectID id, final char delim ) {
- return id.toString(delim);
- }
-
- /**
- * Attempt to convert the specified string to the appropriate ObjectID instance.
- * @param id the stringified id of the form <code>protocol:value</code>, where
- * <code>protocol</code> defines the protocol of the ID, and <code>value</code
- * contains the global identifier value; may never be null
- * @return the ObjectID instance for the stringified ID
- * @throws InvalidIDException if the specified string does not contain a valid ObjectID
- * or if the protocol is unknown
- */
- public ObjectID stringToObject(String id) throws InvalidIDException {
- if (id == null) {
- final String msg = CorePlugin.Util.getString("IDGenerator.The_stringified_ID_may_not_be_null"); //$NON-NLS-1$
- throw new IllegalArgumentException(msg);
- }
-
- // Parse the string
- final ParsedObjectID parsedID = ParsedObjectID.parsedStringifiedObjectID(id,this.protocols);
-
- // Find the appropriate factory and parse the id ...
- final ObjectIDFactory factory = (ObjectIDFactory) this.factories.get(parsedID.getProtocol());
- ObjectID result = null;
- if ( factory != null ) {
- result = factory.stringWithoutProtocolToObject(parsedID.getRemainder());
- }
- if ( result == null ) {
- throw new InvalidIDException(CorePlugin.Util.getString("IDGenerator.The_stringified_ObjectID_has_an_unknown_protocol___16") + parsedID.getProtocol()); //$NON-NLS-1$
- }
- return result;
- }
-
- /**
- * Attempt to convert the specified string to the appropriate ObjectID instance.
- * @param id the stringified id of the form <code>protocol:value</code>, where
- * <code>protocol</code> defines the protocol of the ID, and <code>value</code
- * contains the global identifier value; may never be null
- * @return the ObjectID instance for the stringified ID
- * @throws InvalidIDException if the specified string does not contain a valid ObjectID
- * or if the protocol is unknown
- */
- public ObjectID stringToObject(String id, String protocol) throws InvalidIDException {
- if (id == null) {
- final String msg = CorePlugin.Util.getString("IDGenerator.The_stringified_ID_may_not_be_null"); //$NON-NLS-1$
- throw new IllegalArgumentException(msg);
- }
-
- // Parse the string
- final ParsedObjectID parsedID = ParsedObjectID.parsedStringifiedObjectID(id,protocol);
-
- // Find the appropriate factory and parse the id ...
- final ObjectIDFactory factory = (ObjectIDFactory) this.factories.get(parsedID.getProtocol());
- ObjectID result = null;
- if ( factory != null ) {
- result = factory.stringWithoutProtocolToObject(parsedID.getRemainder());
- }
- if ( result == null ) {
- throw new InvalidIDException(CorePlugin.Util.getString("IDGenerator.The_stringified_ObjectID_has_an_unknown_protocol___16") + parsedID.getProtocol()); //$NON-NLS-1$
- }
- return result;
- }
-
- /**
- * Attempt to convert the specified string to the appropriate ObjectID instance.
- * @param id the stringified id of the form <code>protocol:value</code>, where
- * <code>protocol</code> defines the protocol of the ID, and <code>value</code
- * contains the global identifier value; may never be null
- * @return the ObjectID instance for the stringified ID
- * @throws InvalidIDException if the specified string does not contain a valid ObjectID
- * or if the protocol is unknown
- */
- public ObjectID stringToObject(String id, char delim) throws InvalidIDException {
- if (id == null) {
- final String msg = CorePlugin.Util.getString("IDGenerator.The_stringified_ID_may_not_be_null"); //$NON-NLS-1$
- throw new IllegalArgumentException(msg);
- }
-
- // Parse the string
- final ParsedObjectID parsedID = ParsedObjectID.parsedStringifiedObjectID(id,delim);
-
- // Find the appropriate factory and parse the id ...
- final ObjectIDFactory factory = (ObjectIDFactory) this.factories.get(parsedID.getProtocol());
- ObjectID result = null;
- if ( factory != null ) {
- result = factory.stringWithoutProtocolToObject(parsedID.getRemainder());
- }
- if ( result == null ) {
- throw new InvalidIDException(CorePlugin.Util.getString("IDGenerator.The_stringified_ObjectID_has_an_unknown_protocol___16") + parsedID.getProtocol()); //$NON-NLS-1$
- }
- return result;
- }
-
}
Deleted: trunk/engine/src/main/java/org/teiid/core/id/IntegerID.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/core/id/IntegerID.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/core/id/IntegerID.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -1,125 +0,0 @@
-/*
- * 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.core.id;
-
-import java.io.Serializable;
-
-import org.teiid.core.util.Assertion;
-
-
-public class IntegerID implements ObjectID, Serializable {
-
- public static final String PROTOCOL = "mmint"; //$NON-NLS-1$
- private int id;
-
- protected IntegerID(int id) {
- this.id = id;
- }
- /**
- * Get hash code for object
- * @return Hash code
- */
- public int hashCode() {
- return this.id;
- }
-
- /**
- /**
- * Returns true if the specified object is semantically equal to this instance.
- * Note: this method is consistent with <code>compareTo()</code>.
- * <p>
- * @param obj the object that this instance is to be compared to.
- * @return whether the object is equal to this object.
- */
- public boolean equals(Object obj) {
- // Check if instances are identical ...
- if ( this == obj ) {
- return true;
- }
-
- // Check if object can be compared to this one
- // (this includes checking for null ) ...
- //if ( this.getClass().isInstance(obj) ) {
- if ( obj instanceof IntegerID ) {
- IntegerID that = (IntegerID) obj;
- return ( this.id == that.id );
- }
-
- // Otherwise not comparable ...
- return false;
- }
- /**
- * Compares this object to another. If the specified object is not an instance of
- * the LongID class, then this method throws a
- * ClassCastException (as instances are comparable only to instances of the same
- * class).
- * Note: this method <i>is</i> consistent with <code>equals()</code>, meaning
- * that <code>(compare(x, y)==0) == (x.equals(y))</code>.
- * <p>
- * @param obj the object that this instance is to be compared to; may not be null.
- * @return a negative integer, zero, or a positive integer as this object
- * is less than, equal to, or greater than the specified object, respectively.
- * @throws ClassCastException if the specified object's type prevents it
- * from being compared to this instance.
- */
- public int compareTo(Object obj) {
- IntegerID that = (IntegerID) obj; // May throw ClassCastException
- Assertion.isNotNull(obj);
-
- long diff = this.id - that.id;
- if ( diff < 0 ) {
- return -1;
- }
- if ( diff > 0 ) {
- return 1;
- }
- return 0;
- }
-
- /**
- * Returns a string representing the current state of the object.
- * @return the string representation of this instance.
- */
- public String toString(){
- return PROTOCOL + ObjectID.DELIMITER + this.id;
- }
- /**
- * @see org.teiid.core.id.ObjectID#toString(char)
- */
- public String toString(char delim) {
- return PROTOCOL + delim + this.id;
- }
-
- /**
- * Return the name of the protocol that this factory uses.
- * @return the protocol name
- */
- public String getProtocol() {
- return PROTOCOL;
- }
-
- public int getValue() {
- return this.id;
- }
-}
-
Deleted: trunk/engine/src/main/java/org/teiid/core/id/IntegerIDFactory.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/core/id/IntegerIDFactory.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/core/id/IntegerIDFactory.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -1,116 +0,0 @@
-/*
- * 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.core.id;
-
-import java.io.Serializable;
-
-import org.teiid.core.CorePlugin;
-
-public class IntegerIDFactory implements ObjectIDFactory, Serializable {
- private int lastID = 0;
- public IntegerIDFactory() {
- }
-
- /**
- * Return the description for the type of ObjectID described by this object.
- * @return the description
- */
- public String getDescription() {
- return CorePlugin.Util.getString("IntegerIDFactory.Description"); //$NON-NLS-1$
- }
-
- protected int getNextValue() {
- return ++lastID;
- }
-
- /**
- * Create a new ObjectID instance using this protocol.
- * @return the new instance
- */
- public ObjectID create(){
- return new IntegerID( getNextValue() );
- }
- /**
- * Return whether the specified ObjectID instance is valid. Only ObjectID instances
- * that are for this protocol will be passed in.
- * <p>
- * This implementation only checks whether the ObjectID is an instance of a LongID.
- * @param id the ID that is to be validated, and which is never null
- * @return true if the instance is valid for this protocol, or false if
- * it is not valid.
- */
- public boolean validate(ObjectID id) {
- if ( id instanceof IntegerID ) {
- return true;
- }
- return false;
- }
-
- /**
- * Attempt to convert the specified string to the appropriate ObjectID instance.
- * @param value the stringified id (the result of {@link ObjectID#toString()}),
- * and should never null or zero length
- * @return the ObjectID instance for the stringified ID if this factory is able
- * to parse the string, or null if the factory is unaware of the specified format.
- * @throws InvalidIDException if the parser is aware of this protocol, but it is of the wrong
- * format for this type of ObjectID.
- */
- public ObjectID stringToObject(String value) throws InvalidIDException {
- final ParsedObjectID parsedID = ParsedObjectID.parsedStringifiedObjectID(value,IntegerID.PROTOCOL);
- try {
- return new IntegerID( Integer.parseInt(parsedID.getRemainder()) );
- } catch ( NumberFormatException e ) {
- throw new InvalidIDException(CorePlugin.Util.getString("IntegerIDFactory.The_specified_ID_value_is_invalid",value,getProtocol())); //$NON-NLS-1$
- }
- }
-
- /**
- * Attempt to convert the specified string to the appropriate ObjectID instance.
- * This method is called by the {@link IDGenerator#stringToObject(String)} method, which
- * must process the protocol to determine the correct parser to use. As such, it guarantees
- * that the parser that receives this call can assume that the protocol was equal to the
- * protocol returned by the parser's {@link ObjectIDDescriptor#getProtocol()}.
- * @param value the stringified id with the protocol and ObjectID.DELIMITER already
- * removed, and should never null or zero length
- * @return the ObjectID instance for the stringified ID if this factory is able
- * to parse the string, or null if the factory is unaware of the specified format.
- * @throws InvalidIDException if the parser is aware of this protocol, but it is of the wrong
- * format for this type of ObjectID.
- */
- public ObjectID stringWithoutProtocolToObject(String value) throws InvalidIDException {
- try {
- return new IntegerID( Integer.parseInt(value) );
- } catch ( NumberFormatException e ) {
- throw new InvalidIDException(CorePlugin.Util.getString("IntegerIDFactory.The_specified_ID_value_is_invalid",value,getProtocol())); //$NON-NLS-1$
- }
- }
-
- /**
- * Return the name of the protocol that this factory uses.
- * @return the protocol name
- */
- public String getProtocol() {
- return IntegerID.PROTOCOL;
- }
-}
-
Deleted: trunk/engine/src/main/java/org/teiid/core/id/InvalidIDException.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/core/id/InvalidIDException.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/core/id/InvalidIDException.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -1,70 +0,0 @@
-/*
- * 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.core.id;
-
-import org.teiid.core.CorePlugin;
-import org.teiid.core.TeiidException;
-
-/**
- * Exception which occurs if an error occurs within the server that is not
- * business-related. For instance, if a service or bean is not available
- * or communication fails.
- */
-public class InvalidIDException extends TeiidException {
- private static final String INVALID_ID_MESSAGE = CorePlugin.Util.getString("InvalidIDException.Invalid_ID_1"); //$NON-NLS-1$
-
- /**
- * No-Arg Constructor
- */
- public InvalidIDException( ) {
- super( );
- }
-
-
- /**
- * Construct an instance of InvalidIDException.
- * @param message
- */
- public InvalidIDException(String message) {
- super(message);
- }
-
- /**
- * Construct an instance of InvalidIDException.
- * @param e
- */
- public InvalidIDException(Throwable e) {
- super(e,INVALID_ID_MESSAGE);
- }
-
-
- /**
- * Construct an instance of InvalidIDException.
- * @param e
- * @param message
- */
- public InvalidIDException(Throwable e, String message) {
- super(e, message);
- }
-
-}
Deleted: trunk/engine/src/main/java/org/teiid/core/id/LongID.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/core/id/LongID.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/core/id/LongID.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -1,126 +0,0 @@
-/*
- * 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.core.id;
-
-import java.io.Serializable;
-
-import org.teiid.core.util.Assertion;
-
-
-public class LongID implements ObjectID, Serializable {
- public static final String PROTOCOL = "mmlong"; //$NON-NLS-1$
-
- private long id;
-
- protected LongID(long id) {
- this.id = id;
- }
- /**
- * Get hash code for object
- * @return Hash code
- */
- public int hashCode() {
- return (int) this.id;
- }
-
- /**
- /**
- * Returns true if the specified object is semantically equal to this instance.
- * Note: this method is consistent with <code>compareTo()</code>.
- * <p>
- * @param obj the object that this instance is to be compared to.
- * @return whether the object is equal to this object.
- */
- public boolean equals(Object obj) {
- // Check if instances are identical ...
- if ( this == obj ) {
- return true;
- }
-
- // Check if object can be compared to this one
- // (this includes checking for null ) ...
- //if ( this.getClass().isInstance(obj) ) {
- if ( obj instanceof LongID ) {
- LongID that = (LongID) obj;
- return ( this.id == that.id );
- }
-
- // Otherwise not comparable ...
- return false;
- }
- /**
- * Compares this object to another. If the specified object is not an instance of
- * the LongID class, then this method throws a
- * ClassCastException (as instances are comparable only to instances of the same
- * class).
- * Note: this method <i>is</i> consistent with <code>equals()</code>, meaning
- * that <code>(compare(x, y)==0) == (x.equals(y))</code>.
- * <p>
- * @param obj the object that this instance is to be compared to; may not be null.
- * @return a negative integer, zero, or a positive integer as this object
- * is less than, equal to, or greater than the specified object, respectively.
- * @throws ClassCastException if the specified object's type prevents it
- * from being compared to this instance.
- */
- public int compareTo(Object obj) {
- LongID that = (LongID) obj; // May throw ClassCastException
- Assertion.isNotNull(obj);
-
- long diff = this.id - that.id;
- if ( diff < 0 ) {
- return -1;
- }
- if ( diff > 0 ) {
- return 1;
- }
- return 0;
- }
-
- /**
- * Returns a string representing the current state of the object.
- * @return the string representation of this instance.
- */
- public String toString(){
- return PROTOCOL + ObjectID.DELIMITER + this.id;
- }
-
- /**
- * @see org.teiid.core.id.ObjectID#toString(char)
- */
- public String toString(char delim) {
- return PROTOCOL + delim + this.id;
- }
-
- /**
- * Return the name of the protocol that this factory uses.
- * @return the protocol name
- */
- public String getProtocol() {
- return PROTOCOL;
- }
-
- public long getValue() {
- return this.id;
- }
-}
-
Deleted: trunk/engine/src/main/java/org/teiid/core/id/LongIDFactory.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/core/id/LongIDFactory.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/core/id/LongIDFactory.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -1,117 +0,0 @@
-/*
- * 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.core.id;
-
-import java.io.Serializable;
-
-import org.teiid.core.CorePlugin;
-
-
-public class LongIDFactory implements ObjectIDFactory, Serializable {
- private long lastID = 0;
- public LongIDFactory() {
- }
-
- /**
- * Return the description for the type of ObjectID described by this object.
- * @return the description
- */
- public String getDescription() {
- return CorePlugin.Util.getString("LongIDFactory.Description"); //$NON-NLS-1$
- }
-
- protected long getNextValue() {
- return ++lastID;
- }
-
- /**
- * Create a new ObjectID instance using this protocol.
- * @return the new instance
- */
- public ObjectID create(){
- return new LongID( getNextValue() );
- }
- /**
- * Return whether the specified ObjectID instance is valid. Only ObjectID instances
- * that are for this protocol will be passed in.
- * <p>
- * This implementation only checks whether the ObjectID is an instance of a LongID.
- * @param id the ID that is to be validated, and which is never null
- * @return true if the instance is valid for this protocol, or false if
- * it is not valid.
- */
- public boolean validate(ObjectID id) {
- if ( id instanceof LongID ) {
- return true;
- }
- return false;
- }
-
- /**
- * Attempt to convert the specified string to the appropriate ObjectID instance.
- * This method is called by the {@link IDGenerator#stringToObject(String)} method, which
- * must process the protocol to determine the correct parser to use. As such, it guarantees
- * that the parser that receives this call can assume that the protocol was equal to the
- * protocol returned by the parser's {@link ObjectIDDescriptor#getProtocol()}.
- * @param value the stringified id with the protocol and ObjectID.DELIMITER already
- * removed, and should never null or zero length
- * @return the ObjectID instance for the stringified ID if this factory is able
- * to parse the string, or null if the factory is unaware of the specified format.
- * @throws InvalidIDException if the parser is aware of this protocol, but it is of the wrong
- * format for this type of ObjectID.
- */
- public ObjectID stringWithoutProtocolToObject(String value) throws InvalidIDException {
- try {
- return new LongID( Long.parseLong(value) );
- } catch ( NumberFormatException e ) {
- throw new InvalidIDException(CorePlugin.Util.getString("LongIDFactory.The_specified_ID_value_is_invalid",value,getProtocol())); //$NON-NLS-1$
- }
- }
-
- /**
- * Attempt to convert the specified string to the appropriate ObjectID instance.
- * @param value the stringified id (the result of {@link ObjectID#toString()}),
- * and should never null or zero length
- * @return the ObjectID instance for the stringified ID if this factory is able
- * to parse the string, or null if the factory is unaware of the specified format.
- * @throws InvalidIDException if the parser is aware of this protocol, but it is of the wrong
- * format for this type of ObjectID.
- */
- public ObjectID stringToObject(String value) throws InvalidIDException {
- final ParsedObjectID parsedID = ParsedObjectID.parsedStringifiedObjectID(value,LongID.PROTOCOL);
- try {
- return new LongID( Long.parseLong(parsedID.getRemainder()) );
- } catch ( NumberFormatException e ) {
- throw new InvalidIDException(CorePlugin.Util.getString("LongIDFactory.The_specified_ID_value_is_invalid",value,getProtocol())); //$NON-NLS-1$
- }
- }
-
- /**
- * Return the name of the protocol that this factory uses.
- * @return the protocol name
- */
- public String getProtocol() {
- return LongID.PROTOCOL;
- }
-}
-
Deleted: trunk/engine/src/main/java/org/teiid/core/id/ObjectID.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/core/id/ObjectID.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/core/id/ObjectID.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -1,63 +0,0 @@
-/*
- * 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.core.id;
-
-
-
-public interface ObjectID extends Comparable {
-
- char DELIMITER = ':';
-
- /**
- * Compares this object to another. If the specified object is not an instance of
- * the ObjectID class, then this method throws a
- * ClassCastException (as instances are comparable only to instances of the same
- * class).
- * Note: this method <i>is</i> consistent with <code>equals()</code>, meaning
- * that <code>(compare(x, y)==0) == (x.equals(y))</code>.
- * <p>
- * @param obj the object that this instance is to be compared to; may not be null.
- * @return a negative integer, zero, or a positive integer as this object
- * is less than, equal to, or greater than the specified object, respectively.
- * @throws ClassCastException if the specified object's type prevents it
- * from being compared to this instance.
- */
- int compareTo(Object obj);
- /**
- * Returns a string representing the current state of the object.
- * @return the string representation of this instance.
- */
- String toString();
- /**
- * Returns a string representing the current state of the object.
- * @param delim the delimiter that should be used
- * @return the string representation of this instance.
- */
- String toString( char delim );
- /**
- * Return the name of the protocol that this factory uses.
- * @return the protocol name
- */
- String getProtocol();
-}
-
Deleted: trunk/engine/src/main/java/org/teiid/core/id/ObjectIDFactory.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/core/id/ObjectIDFactory.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/core/id/ObjectIDFactory.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -1,76 +0,0 @@
-/*
- * 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.core.id;
-
-
-/**
- * The ObjectIDDescriptor defines the interface that is used to describe a particular type of
- * {@link ObjectID}.
- */
-public interface ObjectIDFactory {
-
- /**
- * Return the protocol for the type of ObjectID described by this object.
- * @return the protocol
- */
- String getProtocol();
-
- /**
- * Return the description for the type of ObjectID described by this object.
- * @return the description
- */
- String getDescription();
-
- /**
- * Create a new GlobalUID instance using this protocol.
- * @return the new instance
- */
- ObjectID create();
-
- /**
- * Attempt to convert the specified string to the appropriate ObjectID instance.
- * @param value the stringified id (the result of {@link ObjectID#toString()}),
- * and should never null or zero length
- * @return the ObjectID instance for the stringified ID if this factory is able
- * to parse the string, or null if the factory is unaware of the specified format.
- * @throws InvalidIDException if the parser is aware of this protocol, but it is of the wrong
- * format for this type of ObjectID.
- */
- ObjectID stringToObject(String value) throws InvalidIDException;
-
- /**
- * Attempt to convert the specified string to the appropriate ObjectID instance.
- * This method is called by the {@link IDGenerator#stringToObject(String)} method, which
- * must process the protocol to determine the correct parser to use. As such, it guarantees
- * that the parser that receives this call can assume that the protocol was equal to the
- * protocol returned by the parser's {@link ObjectIDDescriptor#getProtocol()}.
- * @param value the stringified id with the protocol and ObjectID.DELIMITER already
- * removed, and should never null or zero length
- * @return the ObjectID instance for the stringified ID if this factory is able
- * to parse the string, or null if the factory is unaware of the specified format.
- * @throws InvalidIDException if the parser is aware of this protocol, but it is of the wrong
- * format for this type of ObjectID.
- */
- ObjectID stringWithoutProtocolToObject(String value) throws InvalidIDException;
-
-}
Deleted: trunk/engine/src/main/java/org/teiid/core/id/ParsedObjectID.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/core/id/ParsedObjectID.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/core/id/ParsedObjectID.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -1,88 +0,0 @@
-/*
- * 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.core.id;
-import java.util.Iterator;
-import java.util.Set;
-
-import org.teiid.core.CorePlugin;
-
-
-/**
- * ParsedObjectID
- */
-public class ParsedObjectID {
- private static final int DELIMITER_LENGTH = 1;
- private final String protocol;
- private final String remainder;
-
- protected ParsedObjectID( final String protocol, final String remainder ) {
- this.protocol = protocol;
- this.remainder = remainder;
- }
-
- public String getProtocol() {
- return protocol;
- }
-
- public String getRemainder() {
- return remainder;
- }
-
- public static ParsedObjectID parsedStringifiedObjectID( final String id, final Set protocols ) throws InvalidIDException {
- final Iterator iter = protocols.iterator();
- while (iter.hasNext()) {
- final String protocol = (String)iter.next();
- if ( id.startsWith(protocol) ) {
- return new ParsedObjectID(protocol,id.substring(protocol.length()+DELIMITER_LENGTH));
- }
- }
- throw new InvalidIDException(CorePlugin.Util.getString("ParsedObjectID.The_stringified_ObjectID_does_not_have_a_protocol")); //$NON-NLS-1$
- }
-
- public static ParsedObjectID parsedStringifiedObjectID( final String id ) throws InvalidIDException {
- return parsedStringifiedObjectID(id,ObjectID.DELIMITER);
- }
-
- public static ParsedObjectID parsedStringifiedObjectID( final String id, final char delim ) throws InvalidIDException {
- int index = -1;
- if ( id != null ) {
- // Obtain the protocol from the string
- index = id.indexOf(delim);
- }
- if ( index == -1 ) {
- throw new InvalidIDException(CorePlugin.Util.getString("ParsedObjectID.The_stringified_ObjectID_does_not_have_a_protocol")); //$NON-NLS-1$
- }
- return new ParsedObjectID(id.substring(0,index),id.substring(index+DELIMITER_LENGTH));
- }
-
- public static ParsedObjectID parsedStringifiedObjectID( final String id, final String expectedProtocol ) throws InvalidIDException {
- if ( expectedProtocol == null ) {
- return new ParsedObjectID("",id); //$NON-NLS-1$
- }
- if ( id.startsWith(expectedProtocol) ) {
- return new ParsedObjectID(expectedProtocol,id.substring(expectedProtocol.length()+DELIMITER_LENGTH));
- }
- throw new InvalidIDException(CorePlugin.Util.getString("ParsedObjectID.The_stringified_ObjectID_does_not_have_the_required_protocol_{0}",expectedProtocol)); //$NON-NLS-1$
- }
-
-}
Deleted: trunk/engine/src/main/java/org/teiid/core/id/StringID.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/core/id/StringID.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/core/id/StringID.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -1,120 +0,0 @@
-/*
- * 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.core.id;
-
-import java.io.Serializable;
-
-import org.teiid.core.util.Assertion;
-
-
-public class StringID implements ObjectID, Serializable {
- public static final String PROTOCOL = "strid"; //$NON-NLS-1$
-
- private String id;
-
- protected StringID(String id) {
- this.id = id;
- }
- protected StringID(long id) {
- this.id = Long.toString(id);
- }
- /**
- * Get hash code for object
- * @return Hash code
- */
- public int hashCode() {
- return id.hashCode();
- }
-
- /**
- /**
- * Returns true if the specified object is semantically equal to this instance.
- * Note: this method is consistent with <code>compareTo()</code>.
- * <p>
- * @param obj the object that this instance is to be compared to.
- * @return whether the object is equal to this object.
- */
- public boolean equals(Object obj) {
- // Check if instances are identical ...
- if ( this == obj ) {
- return true;
- }
-
- // Check if object can be compared to this one
- // (this includes checking for null ) ...
- //if ( this.getClass().isInstance(obj) ) {
- if ( obj instanceof StringID ) {
- StringID that = (StringID) obj;
- return ( this.id.equals( that.id ) );
- }
-
- // Otherwise not comparable ...
- return false;
- }
- /**
- * Compares this object to another. If the specified object is not an instance of
- * the StringID class, then this method throws a
- * ClassCastException (as instances are comparable only to instances of the same
- * class).
- * Note: this method <i>is</i> consistent with <code>equals()</code>, meaning
- * that <code>(compare(x, y)==0) == (x.equals(y))</code>.
- * <p>
- * @param obj the object that this instance is to be compared to; may not be null.
- * @return a negative integer, zero, or a positive integer as this object
- * is less than, equal to, or greater than the specified object, respectively.
- * @throws ClassCastException if the specified object's type prevents it
- * from being compared to this instance.
- */
- public int compareTo(Object obj) {
- StringID that = (StringID) obj; // May throw ClassCastException
- Assertion.isNotNull(obj);
- return this.id.compareTo(that.id);
- }
-
- /**
- * Returns a string representing the current state of the object.
- * @return the string representation of this instance.
- */
- public String toString(){
- return PROTOCOL + ObjectID.DELIMITER + this.id;
- }
- /**
- * @see org.teiid.core.id.ObjectID#toString(char)
- */
- public String toString(char delim) {
- return PROTOCOL + delim + this.id;
- }
-
- /**
- * Return the name of the protocol that this factory uses.
- * @return the protocol name
- */
- public String getProtocol() {
- return PROTOCOL;
- }
-
- protected String getValue() {
- return this.id;
- }
-}
-
Deleted: trunk/engine/src/main/java/org/teiid/core/id/StringIDFactory.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/core/id/StringIDFactory.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/core/id/StringIDFactory.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -1,116 +0,0 @@
-/*
- * 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.core.id;
-
-import org.teiid.core.CorePlugin;
-
-
-
-public class StringIDFactory implements ObjectIDFactory {
- private long lastID = 0;
- public StringIDFactory() {
- }
-
- /**
- * Return the description for the type of ObjectID described by this object.
- * @return the description
- */
- public String getDescription() {
- return CorePlugin.Util.getString("StringIDFactory.Description"); //$NON-NLS-1$
- }
-
- protected long getNextValue() {
- return ++lastID;
- }
-
- /**
- * Create a new ObjectID instance using this protocol.
- * @return the new instance
- */
- public ObjectID create(){
- return new StringID( getNextValue() );
- }
- /**
- * Return whether the specified ObjectID instance is valid. Only ObjectID instances
- * that are for this protocol will be passed in.
- * <p>
- * This implementation only checks whether the ObjectID is an instance of a StringID.
- * @param id the ID that is to be validated, and which is never null
- * @return true if the instance is valid for this protocol, or false if
- * it is not valid.
- */
- public boolean validate(ObjectID id) {
- if ( id instanceof StringID ) {
- return true;
- }
- return false;
- }
-
- /**
- * Attempt to convert the specified string to the appropriate ObjectID instance.
- * This method is called by the {@link IDGenerator#stringToObject(String)} method, which
- * must process the protocol to determine the correct parser to use. As such, it guarantees
- * that the parser that receives this call can assume that the protocol was equal to the
- * protocol returned by the parser's {@link ObjectIDDescriptor#getProtocol()}.
- * @param value the stringified id with the protocol and ObjectID.DELIMITER already
- * removed, and should never null or zero length
- * @return the ObjectID instance for the stringified ID if this factory is able
- * to parse the string, or null if the factory is unaware of the specified format.
- * @throws InvalidIDException if the parser is aware of this protocol, but it is of the wrong
- * format for this type of ObjectID.
- */
- public ObjectID stringWithoutProtocolToObject(String value) throws InvalidIDException {
- try {
- return new StringID( value );
- } catch ( NumberFormatException e ) {
- throw new InvalidIDException(CorePlugin.Util.getString("StringIDFactory.The_specified_ID_value_is_invalid",value,getProtocol())); //$NON-NLS-1$
- }
- }
-
- /**
- * Attempt to convert the specified string to the appropriate ObjectID instance.
- * @param value the stringified id (the result of {@link ObjectID#toString()}),
- * and should never null or zero length
- * @return the ObjectID instance for the stringified ID if this factory is able
- * to parse the string, or null if the factory is unaware of the specified format.
- * @throws InvalidIDException if the parser is aware of this protocol, but it is of the wrong
- * format for this type of ObjectID.
- */
- public ObjectID stringToObject(String value) throws InvalidIDException {
- final ParsedObjectID parsedID = ParsedObjectID.parsedStringifiedObjectID(value,LongID.PROTOCOL);
- try {
- return new StringID( parsedID.getRemainder() );
- } catch ( NumberFormatException e ) {
- throw new InvalidIDException(CorePlugin.Util.getString("StringIDFactory.The_specified_ID_value_is_invalid",value,getProtocol())); //$NON-NLS-1$
- }
- }
-
- /**
- * Return the name of the protocol that this factory uses.
- * @return the protocol name
- */
- public String getProtocol() {
- return StringID.PROTOCOL;
- }
-}
-
Modified: trunk/engine/src/main/java/org/teiid/core/id/UUID.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/core/id/UUID.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/core/id/UUID.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -24,10 +24,7 @@
import java.io.Serializable;
-import org.teiid.core.CorePlugin;
-import org.teiid.core.util.Assertion;
-
/**
* <p>This class represents a universally unique identifier, consisting of
* two long integral values. </p>
@@ -35,10 +32,11 @@
* <p>This identifier is supposed to be unique both spatially and temporally.
* It is based on version 4 IETF variant random UUIDs. </p>
*/
-public class UUID implements ObjectID, Serializable {
+public class UUID implements Serializable {
+
+ private static final long serialVersionUID = 4730187208307761197L;
- private static final String NOT_UUID_MESSAGE = CorePlugin.Util.getString("UUID.ID_must_be_of_type_UUID_1"); //$NON-NLS-1$
- private static final String UNPARSABLE_MESSAGE = CorePlugin.Util.getString("UUID.ID_must_be_of_type_UUID_to_parse_2"); //$NON-NLS-1$
+ char DELIMITER = ':';
/**
* The variants allowed by the UUID specification.
*/
@@ -78,42 +76,6 @@
}
/**
- * Return the first part of the UUID as a long.
- * @return first part of the UUID as a long
- */
- public static long getPart1(ObjectID id) {
- Assertion.assertTrue((id instanceof UUID), UNPARSABLE_MESSAGE);
-
- UUID uuid = (UUID)id;
- return uuid.uuid.getMostSignificantBits();
- }
-
- /**
- * Return the first part of the UUID as a long.
- * @return first part of the UUID as a long
- */
- public static long getPart2(ObjectID id) {
- Assertion.assertTrue((id instanceof UUID), UNPARSABLE_MESSAGE);
-
- UUID uuid = (UUID)id;
- return uuid.uuid.getLeastSignificantBits();
- }
-
- public static int getVariant(ObjectID id ) {
- Assertion.assertTrue((id instanceof UUID), NOT_UUID_MESSAGE);
-
- UUID uuid = (UUID)id;
- return uuid.uuid.variant();
- }
-
- public static int getVersion(ObjectID id ) {
- Assertion.assertTrue((id instanceof UUID), NOT_UUID_MESSAGE);
-
- UUID uuid = (UUID)id;
- return uuid.uuid.version();
- }
-
- /**
* Return the name of the protocol that this factory uses.
* @return the protocol name
*/
@@ -179,7 +141,7 @@
* @return the string representation of this instance.
*/
public String toString(){
- return toString(ObjectID.DELIMITER);
+ return toString(DELIMITER);
}
/**
@@ -206,20 +168,4 @@
return this.cachedExportableFormUuidString;
}
- /**
- * Attempt to convert the specified string to the appropriate ObjectID instance.
- * @param value the stringified id with the protocol and ObjectID.DELIMITER already
- * removed, and which is never null or zero length
- * @return the ObjectID instance for the stringified ID if this factory is able
- * to parse the string, or null if the factory is unaware of the specified format.
- */
- public static ObjectID stringToObject(String value) throws InvalidIDException {
- try {
- return new UUID(java.util.UUID.fromString(value));
- } catch ( IllegalArgumentException e ) {
- throw new InvalidIDException(
- CorePlugin.Util.getString("UUID.InvalidFormatForProtocol",value,PROTOCOL)); //$NON-NLS-1$
- }
- }
-
}
Deleted: trunk/engine/src/main/java/org/teiid/core/id/UUIDFactory.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/core/id/UUIDFactory.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/core/id/UUIDFactory.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -1,132 +0,0 @@
-/*
- * 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.core.id;
-
-import org.teiid.core.CorePlugin;
-
-/**
- * <p>This class is a factory for generating universally unique identifiers
- * (UUID's). </p>
- *
- * <h3>Output format for UUIDs</h3>
- * <p>UUIDs are output in the following 36-character format:
- * <pre>
- * xxxxxxxx-yyyy-zzzz-cccc-nnnnnnnnnnnn
- * </pre>
- * where x=least significant time component, y=middle significant time component,
- * z=most significant time component multiplexed with version, c=clock sequence
- * multiplexed with variant, and n=node component (random number).
- * </p>
- *
- * <p>The generated ID's conform somewhat to the (now expired) IETF internet
- * draft standard, "UUIDs and GUIDs", DCE spec on UUIDs. </p>
- *
- * <ul>
- * <li>
- * <a href="http://hegel.ittc.ukans.edu/topics/internet/internet-drafts/draft-l/draft...">
- * UUIDs and GUIDs, P. Leach, R. Salz, 02/05/1998</a>
- * </li>
- * <li>
- * <a href="http://www.opengroup.org/onlinepubs/009629399/apdxa.htm">
- * DCE Universal Unique Identifier</a>.
- * </li>
- * </ul></p>
- *
- * <p>All references in this code to bit positions as "least significant" and
- * "most significant" refer to the bits moving from right to left, respectively.
- * </p>
- */
-public class UUIDFactory implements ObjectIDFactory {
-
- // -------------------------------------------------------------------------
- // C O N S T R U C T O R
- // -------------------------------------------------------------------------
-
- public UUIDFactory() {
- }
-
- // -------------------------------------------------------------------------
- // P U B L I C M E T H O D S
- // -------------------------------------------------------------------------
-
- /**
- * Return the description for the type of ObjectID described by this object.
- * @return the description
- */
- public String getDescription() {
- return CorePlugin.Util.getString("UUIDFactory.Description"); //$NON-NLS-1$
- }
-
- /**
- * Attempt to convert the specified string to the appropriate ObjectID instance.
- * This method is called by the {@link IDGenerator#stringToObject(String)} method, which
- * must process the protocol to determine the correct parser to use. As such, it guarantees
- * that the parser that receives this call can assume that the protocol was equal to the
- * protocol returned by the parser's {@link ObjectIDDescriptor#getProtocol()}.
- * @param value the stringified id with the protocol and ObjectID.DELIMITER already
- * removed, and should never null or zero length
- * @return the ObjectID instance for the stringified ID if this factory is able
- * to parse the string, or null if the factory is unaware of the specified format.
- * @throws InvalidIDException if the parser is aware of this protocol, but it is of the wrong
- * format for this type of ObjectID.
- */
- public ObjectID stringWithoutProtocolToObject(String value) throws InvalidIDException {
- return UUID.stringToObject(value);
- }
-
- /**
- * Attempt to convert the specified string to the appropriate ObjectID instance.
- * @param value the stringified id (the result of {@link ObjectID#toString()}),
- * and should never null or zero length
- * @return the ObjectID instance for the stringified ID if this factory is able
- * to parse the string, or null if the factory is unaware of the specified format.
- * @throws InvalidIDException if the parser is aware of this protocol, but it is of the wrong
- * format for this type of ObjectID.
- */
- public ObjectID stringToObject(String value) throws InvalidIDException {
- final ParsedObjectID parsedID = ParsedObjectID.parsedStringifiedObjectID(value,UUID.PROTOCOL);
- return UUID.stringToObject(parsedID.getRemainder());
- }
-
- /**
- * Return the name of the protocol that this factory uses.
- * @return the protocol name
- */
- public String getProtocol() {
- return UUID.PROTOCOL;
- }
-
- // -------------------------------------------------------------------------
- // G E N E R A T I O N M E T H O D S
- // -------------------------------------------------------------------------
-
- /**
- * <p>Create a new ObjectID instance using this protocol. </p>
- * @return Universally unique ID (UUID)
- */
- public ObjectID create() {
- return new UUID(java.util.UUID.randomUUID());
- }
-
-}
-
Modified: trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/CapabilitiesConverter.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/CapabilitiesConverter.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/CapabilitiesConverter.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -99,6 +99,9 @@
tgtCaps.setCapabilitySupport(Capability.QUERY_ORDERBY_NULL_ORDERING, srcCaps.supportsOrderByNullOrdering());
tgtCaps.setCapabilitySupport(Capability.INSERT_WITH_ITERATOR, srcCaps.supportsInsertWithIterator());
tgtCaps.setCapabilitySupport(Capability.COMMON_TABLE_EXPRESSIONS, srcCaps.supportsCommonTableExpressions());
+ tgtCaps.setCapabilitySupport(Capability.ADVANCED_OLAP, srcCaps.supportsAdvancedOlapOperations());
+ tgtCaps.setCapabilitySupport(Capability.ELEMENTARY_OLAP, srcCaps.supportsAdvancedOlapOperations());
+ tgtCaps.setCapabilitySupport(Capability.QUERY_AGGREGATES_ARRAY, srcCaps.supportsArrayAgg());
List functions = srcCaps.getSupportedFunctions();
if(functions != null && functions.size() > 0) {
Iterator iter = functions.iterator();
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-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/LanguageBridgeFactory.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -570,10 +570,12 @@
}
AggregateFunction translate(AggregateSymbol symbol) {
- return new AggregateFunction(symbol.getAggregateFunction().name(),
+ AggregateFunction af = new AggregateFunction(symbol.getAggregateFunction().name(),
symbol.isDistinct(),
translate(symbol.getExpression()),
symbol.getType());
+ af.setCondition(translate(symbol.getCondition()));
+ return af;
}
org.teiid.language.Expression translate(ExpressionSymbol symbol) {
Modified: trunk/engine/src/main/java/org/teiid/dqp/internal/process/Request.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/dqp/internal/process/Request.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/process/Request.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -43,7 +43,6 @@
import org.teiid.core.TeiidComponentException;
import org.teiid.core.TeiidProcessingException;
import org.teiid.core.id.IDGenerator;
-import org.teiid.core.id.IntegerIDFactory;
import org.teiid.core.types.DataTypeManager;
import org.teiid.core.util.Assertion;
import org.teiid.dqp.internal.datamgr.ConnectorManagerRepository;
@@ -150,7 +149,6 @@
this.processorDataManager = processorDataManager;
this.transactionService = transactionService;
this.tempTableStore = tempTableStore;
- idGenerator.setDefaultFactory(new IntegerIDFactory());
this.workContext = workContext;
this.requestId = workContext.getRequestID(this.requestMsg.getExecutionId());
this.connectorManagerRepo = workContext.getVDB().getAttachment(ConnectorManagerRepository.class);
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/BatchedUpdatePlanner.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/BatchedUpdatePlanner.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/BatchedUpdatePlanner.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -30,7 +30,6 @@
import org.teiid.core.TeiidComponentException;
import org.teiid.core.TeiidRuntimeException;
import org.teiid.core.id.IDGenerator;
-import org.teiid.core.id.IntegerID;
import org.teiid.query.QueryPlugin;
import org.teiid.query.analysis.AnalysisRecord;
import org.teiid.query.metadata.QueryMetadataInterface;
@@ -142,9 +141,9 @@
}
// If two or more contiguous commands made on the same model were found, then batch them
if (batch.size() > 1) {
- ProjectNode projectNode = new ProjectNode(((IntegerID)idGenerator.create()).getValue());
+ ProjectNode projectNode = new ProjectNode(idGenerator.nextInt());
// Create a BatchedUpdateNode that creates a batched request for the connector
- BatchedUpdateNode batchNode = new BatchedUpdateNode(((IntegerID)idGenerator.create()).getValue(),
+ BatchedUpdateNode batchNode = new BatchedUpdateNode(idGenerator.nextInt(),
batch, contexts, shouldEvaluate,
modelName);
List symbols = batchedUpdateCommand.getProjectedSymbols();
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/QueryOptimizer.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/QueryOptimizer.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/QueryOptimizer.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -34,7 +34,6 @@
import org.teiid.core.TeiidProcessingException;
import org.teiid.core.TeiidRuntimeException;
import org.teiid.core.id.IDGenerator;
-import org.teiid.core.id.IntegerIDFactory;
import org.teiid.dqp.internal.process.PreparedPlan;
import org.teiid.metadata.Procedure;
import org.teiid.metadata.FunctionMethod.Determinism;
@@ -99,7 +98,6 @@
// Create an ID generator that can be used for all plans to generate unique data node IDs
if(idGenerator == null) {
idGenerator = new IDGenerator();
- idGenerator.setDefaultFactory(new IntegerIDFactory());
}
if(debug) {
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/capabilities/SourceCapabilities.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/capabilities/SourceCapabilities.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/capabilities/SourceCapabilities.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -321,6 +321,9 @@
INSERT_WITH_ITERATOR,
COMMON_TABLE_EXPRESSIONS,
MAX_DEPENDENT_PREDICATES,
+ ADVANCED_OLAP,
+ QUERY_AGGREGATES_ARRAY,
+ ELEMENTARY_OLAP
}
public enum Scope {
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/PlanToProcessConverter.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/PlanToProcessConverter.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/PlanToProcessConverter.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -32,8 +32,6 @@
import org.teiid.core.CoreConstants;
import org.teiid.core.TeiidComponentException;
import org.teiid.core.id.IDGenerator;
-import org.teiid.core.id.IntegerID;
-import org.teiid.core.id.IntegerIDFactory;
import org.teiid.core.util.Assertion;
import org.teiid.query.QueryPlugin;
import org.teiid.query.analysis.AnalysisRecord;
@@ -53,6 +51,7 @@
import org.teiid.query.processor.relational.DependentAccessNode;
import org.teiid.query.processor.relational.DependentProcedureAccessNode;
import org.teiid.query.processor.relational.DependentProcedureExecutionNode;
+import org.teiid.query.processor.relational.EnhancedSortMergeJoinStrategy;
import org.teiid.query.processor.relational.GroupingNode;
import org.teiid.query.processor.relational.InsertPlanExecutionNode;
import org.teiid.query.processor.relational.JoinNode;
@@ -61,7 +60,6 @@
import org.teiid.query.processor.relational.NestedLoopJoinStrategy;
import org.teiid.query.processor.relational.NestedTableJoinStrategy;
import org.teiid.query.processor.relational.NullNode;
-import org.teiid.query.processor.relational.EnhancedSortMergeJoinStrategy;
import org.teiid.query.processor.relational.PlanExecutionNode;
import org.teiid.query.processor.relational.ProjectIntoNode;
import org.teiid.query.processor.relational.ProjectNode;
@@ -169,8 +167,7 @@
}
protected int getID() {
- IntegerIDFactory intFactory = (IntegerIDFactory) idGenerator.getDefaultFactory();
- return ((IntegerID) intFactory.create()).getValue();
+ return idGenerator.nextInt();
}
protected RelationalNode convertNode(PlanNode node)
@@ -377,7 +374,8 @@
break;
case NodeConstants.Types.GROUP:
GroupingNode gnode = new GroupingNode(getID());
- gnode.setGroupingElements( (List) node.getProperty(NodeConstants.Info.GROUP_COLS) );
+ gnode.setGroupingElements( (List<Expression>) node.getProperty(NodeConstants.Info.GROUP_COLS) );
+ gnode.setOutputMapping((SymbolMap)node.getProperty(NodeConstants.Info.SYMBOL_MAP));
gnode.setRemoveDuplicates(node.hasBooleanProperty(NodeConstants.Info.IS_DUP_REMOVAL));
processNode = gnode;
break;
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-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -27,6 +27,8 @@
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -45,9 +47,11 @@
import org.teiid.query.QueryPlugin;
import org.teiid.query.analysis.AnalysisRecord;
import org.teiid.query.mapping.relational.QueryNode;
+import org.teiid.query.metadata.BasicQueryMetadata;
import org.teiid.query.metadata.QueryMetadataInterface;
import org.teiid.query.metadata.TempMetadataAdapter;
import org.teiid.query.metadata.TempMetadataID;
+import org.teiid.query.metadata.TempMetadataStore;
import org.teiid.query.optimizer.QueryOptimizer;
import org.teiid.query.optimizer.TriggerActionPlanner;
import org.teiid.query.optimizer.capabilities.CapabilitiesFinder;
@@ -62,6 +66,8 @@
import org.teiid.query.optimizer.relational.rules.RuleCollapseSource;
import org.teiid.query.optimizer.relational.rules.RuleConstants;
import org.teiid.query.optimizer.relational.rules.RuleMergeCriteria;
+import org.teiid.query.optimizer.relational.rules.RulePlaceAccess;
+import org.teiid.query.optimizer.relational.rules.RulePushAggregates;
import org.teiid.query.processor.ProcessorPlan;
import org.teiid.query.processor.relational.AccessNode;
import org.teiid.query.processor.relational.RelationalPlan;
@@ -104,9 +110,13 @@
import org.teiid.query.sql.navigator.PreOrPostOrderNavigator;
import org.teiid.query.sql.proc.CreateUpdateProcedureCommand;
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.AllSymbol;
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.Reference;
import org.teiid.query.sql.symbol.ScalarSubquery;
@@ -115,6 +125,8 @@
import org.teiid.query.sql.util.SymbolMap;
import org.teiid.query.sql.visitor.AggregateSymbolCollectorVisitor;
import org.teiid.query.sql.visitor.CorrelatedReferenceCollectorVisitor;
+import org.teiid.query.sql.visitor.ElementCollectorVisitor;
+import org.teiid.query.sql.visitor.ExpressionMappingVisitor;
import org.teiid.query.sql.visitor.GroupsUsedByElementsVisitor;
import org.teiid.query.sql.visitor.ValueIteratorProviderCollectorVisitor;
import org.teiid.query.util.CommandContext;
@@ -401,7 +413,7 @@
rules.push(RuleConstants.PLAN_PROCEDURES);
}
if(hints.hasAggregates) {
- rules.push(RuleConstants.PUSH_AGGREGATES);
+ rules.push(new RulePushAggregates(idGenerator));
}
if(hints.hasJoin) {
rules.push(RuleConstants.CHOOSE_DEPENDENT);
@@ -729,9 +741,18 @@
}
// Attach grouping node on top
- if(query.hasAggregates()) {
- plan = attachGrouping(plan, query, hints);
+ Collection<AggregateSymbol> aggs = AggregateSymbolCollectorVisitor.getAggregates(query.getSelect(), true);
+ boolean hasGrouping = !aggs.isEmpty();
+ if (query.getHaving() != null) {
+ AggregateSymbolCollectorVisitor.getAggregates(query.getHaving(), aggs, null);
+ hasGrouping = true;
}
+ if (query.getGroupBy() != null) {
+ hasGrouping = true;
+ }
+ if(hasGrouping) {
+ plan = attachGrouping(plan, query, aggs);
+ }
// Attach having criteria node on top
if(query.getHaving() != null) {
@@ -982,7 +1003,7 @@
public static PlanNode createSelectNode(final Criteria crit, boolean isHaving) {
PlanNode critNode = NodeFactory.getNewNode(NodeConstants.Types.SELECT);
critNode.setProperty(NodeConstants.Info.SELECT_CRITERIA, crit);
- if (isHaving && !AggregateSymbolCollectorVisitor.getAggregates(crit, false).isEmpty()) {
+ if (isHaving && !ElementCollectorVisitor.getAggregates(crit, false).isEmpty()) {
critNode.setProperty(NodeConstants.Info.IS_HAVING, Boolean.TRUE);
}
// Add groups to crit node
@@ -994,19 +1015,29 @@
/**
* Attach a grouping node at top of tree.
* @param plan Existing plan
+ * @param aggs
* @param groupBy Group by clause, which may be null
* @return Updated plan
+ * @throws TeiidComponentException
+ * @throws QueryMetadataException
*/
- private static PlanNode attachGrouping(PlanNode plan, Query query, PlanHints hints) {
- PlanNode groupNode = NodeFactory.getNewNode(NodeConstants.Types.GROUP);
-
+ private PlanNode attachGrouping(PlanNode plan, Query query, Collection<AggregateSymbol> aggs) throws QueryMetadataException, TeiidComponentException {
+ //TODO: correlated agg
+
GroupBy groupBy = query.getGroupBy();
- if(groupBy != null) {
- groupNode.setProperty(NodeConstants.Info.GROUP_COLS, groupBy.getSymbols());
- groupNode.addGroups(GroupsUsedByElementsVisitor.getGroups(groupBy));
+ List<Expression> groupingCols = null;
+ if (groupBy != null) {
+ groupingCols = groupBy.getSymbols();
}
+
+ PlanNode groupNode = NodeFactory.getNewNode(NodeConstants.Types.GROUP);
+
+ Map<Expression, ElementSymbol> mapping = buildGroupingNode(aggs, groupingCols, groupNode, this.context, this.idGenerator).inserseMapping();
attachLast(groupNode, plan);
+ ExpressionMappingVisitor.mapExpressions(query.getHaving(), mapping);
+ ExpressionMappingVisitor.mapExpressions(query.getSelect(), mapping);
+ ExpressionMappingVisitor.mapExpressions(query.getOrderBy(), mapping);
// Mark in hints
hints.hasAggregates = true;
@@ -1014,6 +1045,57 @@
return groupNode;
}
+ /**
+ * Build a grouping node that introduces a anon group (without a inline view source node)
+ */
+ public static SymbolMap buildGroupingNode(
+ Collection<AggregateSymbol> aggs, List<? extends Expression> groupingCols,
+ PlanNode groupNode, CommandContext cc, IDGenerator idGenerator) throws QueryMetadataException, TeiidComponentException {
+ SymbolMap map = new SymbolMap();
+ aggs = LanguageObject.Util.deepClone(aggs, AggregateSymbol.class);
+ groupingCols = LanguageObject.Util.deepClone(groupingCols, Expression.class);
+ GroupSymbol group = new GroupSymbol("anon_grp" + idGenerator.nextInt()); //$NON-NLS-1$
+ if (!cc.getGroups().add(group.getName())) {
+ group = RulePlaceAccess.recontextSymbol(group, cc.getGroups());
+ }
+
+ TempMetadataStore tms = new TempMetadataStore();
+
+ int i = 0;
+
+ List<AliasSymbol> symbols = new LinkedList<AliasSymbol>();
+ List<Expression> targets = new LinkedList<Expression>();
+
+ if(groupingCols != null) {
+ groupNode.setProperty(NodeConstants.Info.GROUP_COLS, groupingCols);
+ groupNode.addGroups(GroupsUsedByElementsVisitor.getGroups(groupingCols));
+ for (Expression ex : groupingCols) {
+ AliasSymbol as = new AliasSymbol("gcol" + i++, new ExpressionSymbol("expr", ex)); //$NON-NLS-1$ //$NON-NLS-2$
+ targets.add(ex);
+ symbols.add(as);
+ }
+ }
+
+ i = 0;
+ for (AggregateSymbol ex : aggs) {
+ AliasSymbol as = new AliasSymbol("agg" + i++, new ExpressionSymbol("expr", ex)); //$NON-NLS-1$ //$NON-NLS-2$
+ targets.add(ex);
+ symbols.add(as);
+ }
+
+ group.setMetadataID(tms.addTempGroup(group.getName(), symbols, true, false));
+ Iterator<Expression> targetIter = targets.iterator();
+ for (ElementSymbol es : ResolverUtil.resolveElementsInGroup(group, new TempMetadataAdapter(new BasicQueryMetadata(), tms))) {
+ Expression target = targetIter.next();
+ es.setAggregate(target instanceof AggregateSymbol);
+ map.addMapping(es, target);
+ }
+
+ groupNode.setProperty(NodeConstants.Info.SYMBOL_MAP, map);
+ groupNode.addGroup(group);
+ return map;
+ }
+
/**
* Attach SORT node at top of tree. The SORT may be pushed down to a source (or sources)
* if possible by the optimizer.
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-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/plantree/NodeConstants.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -130,7 +130,7 @@
MAKE_IND,
// Group node properties
- GROUP_COLS, // List <SingleElementSymbol>
+ GROUP_COLS, // List <Expression>
// Special constant used in converting plan to process for all nodes
OUTPUT_COLS, // List <SingleElementSymbol>
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-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/CapabilitiesUtil.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -120,12 +120,13 @@
return false;
}
boolean supportsFunctionsInGroupBy = caps.supportsCapability(Capability.QUERY_FUNCTIONS_IN_GROUP_BY);
+ boolean supportsInlineView = caps.supportsCapability(Capability.QUERY_FROM_INLINE_VIEWS);
// Also verify that if there is a function that we can support pushdown of functions in group by
Iterator colIter = groupCols.iterator();
while(colIter.hasNext()) {
Expression col = (Expression) colIter.next();
- if(!(col instanceof ElementSymbol) && !supportsFunctionsInGroupBy) {
+ if(!(col instanceof ElementSymbol) && !supportsFunctionsInGroupBy && !supportsInlineView) {
// Function in GROUP BY can't be pushed
return false;
}
@@ -179,6 +180,11 @@
return false;
}
break;
+ case ARRAY_AGG:
+ if(! caps.supportsCapability(Capability.QUERY_AGGREGATES_ARRAY)) {
+ return false;
+ }
+ break;
default:
if (aggregate.isEnhancedNumeric()) {
if (!caps.supportsCapability(Capability.QUERY_AGGREGATES_ENHANCED_NUMERIC)) {
@@ -195,10 +201,12 @@
return false;
}
+ if (aggregate.getCondition() != null && !caps.supportsCapability(Capability.ADVANCED_OLAP)) {
+ return false;
+ }
+
// Passed all the checks!
return true;
-
-
}
public static boolean supportsScalarFunction(Object modelID, Function function, QueryMetadataInterface metadata, CapabilitiesFinder capFinder)
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/FrameUtil.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/FrameUtil.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/FrameUtil.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -45,6 +45,7 @@
import org.teiid.query.optimizer.relational.plantree.NodeEditor;
import org.teiid.query.optimizer.relational.plantree.NodeFactory;
import org.teiid.query.optimizer.relational.plantree.PlanNode;
+import org.teiid.query.optimizer.relational.plantree.NodeConstants.Info;
import org.teiid.query.processor.ProcessorPlan;
import org.teiid.query.resolver.util.AccessPattern;
import org.teiid.query.resolver.util.ResolverUtil;
@@ -178,6 +179,10 @@
// multiple new groups.
static void convertNode(PlanNode node, GroupSymbol oldGroup, Set<GroupSymbol> newGroups, Map symbolMap, QueryMetadataInterface metadata, boolean rewrite)
throws QueryPlannerException {
+
+ if (node.getType() == NodeConstants.Types.GROUP) {
+ correctSymbolMap(symbolMap, node);
+ }
// Convert expressions from correlated subquery references;
List<SymbolMap> refMaps = node.getAllReferences();
@@ -256,7 +261,7 @@
GroupsUsedByElementsVisitor.getGroups(orderBy, groups);
}
} else if(type == NodeConstants.Types.GROUP) {
- List<SingleElementSymbol> groupCols = (List<SingleElementSymbol>)node.getProperty(NodeConstants.Info.GROUP_COLS);
+ List<Expression> groupCols = (List<Expression>)node.getProperty(NodeConstants.Info.GROUP_COLS);
if (groupCols != null) {
GroupBy groupBy= new GroupBy(groupCols);
ExpressionMappingVisitor.mapExpressions(groupBy, symbolMap);
@@ -265,6 +270,10 @@
GroupsUsedByElementsVisitor.getGroups(groupBy, groups);
}
}
+ if (!singleMapping) {
+ //add back the anon group
+ groups.add(((SymbolMap)node.getProperty(Info.SYMBOL_MAP)).asMap().keySet().iterator().next().getGroupSymbol());
+ }
} else if (type == NodeConstants.Types.SOURCE || type == NodeConstants.Types.ACCESS) {
convertAccessPatterns(symbolMap, node);
}
@@ -281,7 +290,9 @@
if (mappedSymbol != null) {
return mappedSymbol;
}
- return expression;
+ if (expression instanceof ElementSymbol) {
+ return expression;
+ }
}
ExpressionMappingVisitor.mapExpressions(expression, symbolMap);
@@ -377,8 +388,7 @@
private static PlanNode findOriginatingNode(PlanNode root, Set<GroupSymbol> groups, boolean joinSource) {
boolean containsGroups = false;
- if(root.getType() == NodeConstants.Types.NULL || root.getType() == NodeConstants.Types.SOURCE
- || root.getType() == NodeConstants.Types.JOIN || root.getType() == NodeConstants.Types.SET_OP ||
+ if((root.getType() & (NodeConstants.Types.NULL | NodeConstants.Types.SOURCE | NodeConstants.Types.JOIN | NodeConstants.Types.SET_OP | NodeConstants.Types.GROUP)) == root.getType() ||
(joinSource && root.getType() == NodeConstants.Types.ACCESS)) {
//if there are no groups then the first possible match is the one we want
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/NewCalculateCostUtil.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/NewCalculateCostUtil.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/NewCalculateCostUtil.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -74,7 +74,6 @@
import org.teiid.query.sql.symbol.GroupSymbol;
import org.teiid.query.sql.symbol.SingleElementSymbol;
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.EvaluatableVisitor;
import org.teiid.query.sql.visitor.GroupsUsedByElementsVisitor;
@@ -440,7 +439,7 @@
if (stats == null) {
if (node.getType() == NodeConstants.Types.PROJECT) {
Collection<SingleElementSymbol> elems = new HashSet<SingleElementSymbol>();
- AggregateSymbolCollectorVisitor.getAggregates(expr, elems, elems);
+ ElementCollectorVisitor.getElements(expr, elems);
newStats[Stat.NDV.ordinal()] = getStat(Stat.NDV, elems, node, childCardinality, metadata);
newStats[Stat.NNV.ordinal()] = getStat(Stat.NNV, elems, node, childCardinality, metadata);
} else {
@@ -578,9 +577,8 @@
if (node.getType() == NodeConstants.Types.PROJECT) {
return (List<? extends Expression>) node.getProperty(NodeConstants.Info.PROJECT_COLS);
} else if (node.getType() == NodeConstants.Types.GROUP) {
- LinkedList<Expression> result = new LinkedList<Expression>(RulePushAggregates.collectAggregates(node));
- result.addAll((Collection<? extends Expression>) node.getProperty(Info.GROUP_COLS));
- return result;
+ SymbolMap map = (SymbolMap)node.getProperty(Info.SYMBOL_MAP);
+ return map.getKeys();
}
LinkedList<ElementSymbol> elements = new LinkedList<ElementSymbol>();
for (GroupSymbol group : node.getGroups()) {
@@ -1014,7 +1012,7 @@
return cost;
}
- static boolean usesKey(PlanNode planNode, Collection<? extends SingleElementSymbol> allElements, QueryMetadataInterface metadata) throws QueryMetadataException, TeiidComponentException {
+ static boolean usesKey(PlanNode planNode, Collection<? extends Expression> allElements, QueryMetadataInterface metadata) throws QueryMetadataException, TeiidComponentException {
//TODO: key preserved joins should be marked
return isSingleTable(planNode)
&& usesKey(allElements, metadata);
@@ -1035,17 +1033,17 @@
* we are in the plan.
* if a key column is used after a non 1-1 join or a union all, then it may be non-unique.
*/
- public static boolean usesKey(Collection<? extends SingleElementSymbol> allElements, QueryMetadataInterface metadata)
+ public static boolean usesKey(Collection<? extends Expression> allElements, QueryMetadataInterface metadata)
throws QueryMetadataException, TeiidComponentException {
return usesKey(allElements, null, metadata, true);
}
- public static boolean usesKey(Collection<? extends SingleElementSymbol> allElements, Set<GroupSymbol> groups, QueryMetadataInterface metadata, boolean unique)
+ public static boolean usesKey(Collection<? extends Expression> allElements, Set<GroupSymbol> groups, QueryMetadataInterface metadata, boolean unique)
throws QueryMetadataException, TeiidComponentException {
return getKeyUsed(allElements, groups, metadata, unique) != null;
}
- public static Object getKeyUsed(Collection<? extends SingleElementSymbol> allElements, Set<GroupSymbol> groups, QueryMetadataInterface metadata, Boolean unique)
+ public static Object getKeyUsed(Collection<? extends Expression> allElements, Set<GroupSymbol> groups, QueryMetadataInterface metadata, Boolean unique)
throws QueryMetadataException, TeiidComponentException {
if(allElements == null || allElements.size() == 0) {
@@ -1054,7 +1052,7 @@
// Sort elements into groups
Map<GroupSymbol, List<Object>> groupMap = new HashMap<GroupSymbol, List<Object>>();
- for (SingleElementSymbol ses : allElements) {
+ for (Expression ses : allElements) {
Expression ex = SymbolMap.getExpression(ses);
if (!(ex instanceof ElementSymbol)) {
continue; //TODO: function based indexes are possible, but we don't have the metadata
@@ -1337,7 +1335,7 @@
static float getNDVEstimate(PlanNode indNode,
QueryMetadataInterface metadata, float cardinality,
- Collection<? extends SingleElementSymbol> elems, boolean useCardinalityIfUnknown) throws QueryMetadataException,
+ Collection<? extends Expression> elems, boolean useCardinalityIfUnknown) throws QueryMetadataException,
TeiidComponentException {
if (elems == null || elems.isEmpty()) {
return cardinality;
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleAssignOutputElements.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleAssignOutputElements.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleAssignOutputElements.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -57,7 +57,7 @@
import org.teiid.query.sql.symbol.GroupSymbol;
import org.teiid.query.sql.symbol.SingleElementSymbol;
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.GroupsUsedByElementsVisitor;
import org.teiid.query.util.CommandContext;
@@ -437,8 +437,6 @@
* are any symbols that are required in the processing of this node,
* for instance to create a new element symbol or sort on it, etc.
* @param node Node to collect for
- * @param requiredSymbols Collection<SingleElementSymbol> Place to collect required symbols
- * @param createdSymbols Set<SingleElementSymbol> Place to collect any symbols created by this node
*/
private List<SingleElementSymbol> collectRequiredInputSymbols(PlanNode node) {
@@ -459,57 +457,53 @@
}
if (ss instanceof ExpressionSymbol && !(ss instanceof AggregateSymbol)) {
- ExpressionSymbol exprSymbol = (ExpressionSymbol)ss;
-
- if (!exprSymbol.isDerivedExpression()) {
- createdSymbols.add(ss);
- }
+ createdSymbols.add(ss);
}
- AggregateSymbolCollectorVisitor.getAggregates(ss, requiredSymbols, requiredSymbols);
+ ElementCollectorVisitor.getElements(ss, requiredSymbols);
}
break;
}
case NodeConstants.Types.SELECT:
Criteria selectCriteria = (Criteria) node.getProperty(NodeConstants.Info.SELECT_CRITERIA);
- AggregateSymbolCollectorVisitor.getAggregates(selectCriteria, requiredSymbols, requiredSymbols);
+ ElementCollectorVisitor.getElements(selectCriteria, requiredSymbols);
break;
case NodeConstants.Types.JOIN:
List<Criteria> crits = (List) node.getProperty(NodeConstants.Info.JOIN_CRITERIA);
if(crits != null) {
for (Criteria joinCriteria : crits) {
- AggregateSymbolCollectorVisitor.getAggregates(joinCriteria, requiredSymbols, requiredSymbols);
+ ElementCollectorVisitor.getElements(joinCriteria, requiredSymbols);
}
}
break;
case NodeConstants.Types.GROUP:
- List<SingleElementSymbol> groupCols = (List<SingleElementSymbol>) node.getProperty(NodeConstants.Info.GROUP_COLS);
+ List<Expression> groupCols = (List<Expression>) node.getProperty(NodeConstants.Info.GROUP_COLS);
if(groupCols != null) {
- for (SingleElementSymbol expression : groupCols) {
- if(expression instanceof ElementSymbol || expression instanceof AggregateSymbol) {
- requiredSymbols.add(expression);
- } else {
- ExpressionSymbol exprSymbol = (ExpressionSymbol) expression;
- Expression expr = exprSymbol.getExpression();
- AggregateSymbolCollectorVisitor.getAggregates(expr, requiredSymbols, requiredSymbols);
- createdSymbols.add(exprSymbol);
- }
+ for (Expression expression : groupCols) {
+ ElementCollectorVisitor.getElements(expression, requiredSymbols);
}
}
-
+
+ SymbolMap symbolMap = (SymbolMap) node.getProperty(NodeConstants.Info.SYMBOL_MAP);
+
// Take credit for creating any aggregates that are needed above
for (SingleElementSymbol outputSymbol : outputCols) {
- if(outputSymbol instanceof AggregateSymbol) {
- AggregateSymbol agg = (AggregateSymbol)outputSymbol;
- createdSymbols.add(outputSymbol);
+ createdSymbols.add(outputSymbol);
+ Expression ex = symbolMap.getMappedExpression((ElementSymbol) outputSymbol);
+ if(ex instanceof AggregateSymbol) {
+ AggregateSymbol agg = (AggregateSymbol)ex;
Expression aggExpr = agg.getExpression();
if(aggExpr != null) {
- AggregateSymbolCollectorVisitor.getAggregates(aggExpr, requiredSymbols, requiredSymbols);
+ ElementCollectorVisitor.getElements(aggExpr, requiredSymbols);
}
OrderBy orderBy = agg.getOrderBy();
if(orderBy != null) {
- AggregateSymbolCollectorVisitor.getAggregates(orderBy, requiredSymbols, requiredSymbols);
+ ElementCollectorVisitor.getElements(orderBy, requiredSymbols);
}
+ Expression condition = agg.getCondition();
+ if(condition != null) {
+ ElementCollectorVisitor.getElements(condition, requiredSymbols);
+ }
}
}
@@ -519,7 +513,7 @@
// Gather elements from correlated subquery references;
for (SymbolMap refs : node.getAllReferences()) {
for (Expression expr : refs.asMap().values()) {
- AggregateSymbolCollectorVisitor.getAggregates(expr, requiredSymbols, requiredSymbols);
+ ElementCollectorVisitor.getElements(expr, requiredSymbols);
}
}
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleChooseJoinStrategy.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleChooseJoinStrategy.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleChooseJoinStrategy.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -71,7 +71,6 @@
* Determines whether this node should be converted to a merge join node
* @param joinNode The join node
* @param metadata The metadata
- * @return True if merge is possible
*/
static void chooseJoinStrategy(PlanNode joinNode, QueryMetadataInterface metadata) {
// Check that join is an inner join
@@ -183,7 +182,6 @@
ExpressionSymbol expressionSymbol = uniqueExpressions.get(expression);
if (expressionSymbol == null) {
expressionSymbol = new ExpressionSymbol("$" + EXPRESSION_INDEX.getAndIncrement(), expression); //$NON-NLS-1$
- expressionSymbol.setDerivedExpression(true);
uniqueExpressions.put(expression, expressionSymbol);
}
result.add(expressionSymbol);
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleCollapseSource.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleCollapseSource.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleCollapseSource.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -24,14 +24,19 @@
import java.util.ArrayList;
import java.util.Collection;
+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.Set;
import org.teiid.api.exception.query.QueryMetadataException;
import org.teiid.api.exception.query.QueryPlannerException;
import org.teiid.core.TeiidComponentException;
+import org.teiid.core.TeiidException;
+import org.teiid.core.TeiidRuntimeException;
import org.teiid.core.types.DataTypeManager;
import org.teiid.query.analysis.AnalysisRecord;
import org.teiid.query.metadata.QueryMetadataInterface;
@@ -72,6 +77,7 @@
import org.teiid.query.sql.lang.UnaryFromClause;
import org.teiid.query.sql.lang.SetQuery.Operation;
import org.teiid.query.sql.navigator.DeepPostOrderNavigator;
+import org.teiid.query.sql.symbol.AggregateSymbol;
import org.teiid.query.sql.symbol.Constant;
import org.teiid.query.sql.symbol.ElementSymbol;
import org.teiid.query.sql.symbol.Expression;
@@ -80,6 +86,7 @@
import org.teiid.query.sql.symbol.ScalarSubquery;
import org.teiid.query.sql.symbol.SingleElementSymbol;
import org.teiid.query.sql.util.SymbolMap;
+import org.teiid.query.sql.visitor.AggregateSymbolCollectorVisitor;
import org.teiid.query.sql.visitor.ExpressionMappingVisitor;
import org.teiid.query.sql.visitor.ValueIteratorProviderCollectorVisitor;
import org.teiid.query.util.CommandContext;
@@ -241,11 +248,12 @@
if (query.getCriteria() instanceof CompoundCriteria) {
query.setCriteria(QueryRewriter.optimizeCriteria((CompoundCriteria)query.getCriteria(), metadata));
}
- if (!CapabilitiesUtil.useAnsiJoin(RuleRaiseAccess.getModelIDFromAccess(accessRoot, metadata), metadata, capFinder)) {
+ Object modelID = RuleRaiseAccess.getModelIDFromAccess(accessRoot, metadata);
+ if (!CapabilitiesUtil.useAnsiJoin(modelID, metadata, capFinder)) {
simplifyFromClause(query);
}
if (columns.isEmpty()) {
- if (CapabilitiesUtil.supports(Capability.QUERY_SELECT_EXPRESSION, RuleRaiseAccess.getModelIDFromAccess(accessRoot, metadata), metadata, capFinder)) {
+ if (CapabilitiesUtil.supports(Capability.QUERY_SELECT_EXPRESSION, modelID, metadata, capFinder)) {
select.addSymbol(new ExpressionSymbol("dummy", new Constant(1))); //$NON-NLS-1$
} else {
//TODO: need to ensure the type is consistent
@@ -253,6 +261,20 @@
select.addSymbol(selectOutputElement(query.getFrom().getGroups(), metadata));
}
}
+ PlanNode groupNode = NodeEditor.findNodePreOrder(node, NodeConstants.Types.GROUP, NodeConstants.Types.SOURCE);
+ if (groupNode != null) {
+ SymbolMap symbolMap = (SymbolMap) groupNode.getProperty(NodeConstants.Info.SYMBOL_MAP);
+
+ //map back to expression form
+ ExpressionMappingVisitor.mapExpressions(query.getOrderBy(), symbolMap.asMap());
+ ExpressionMappingVisitor.mapExpressions(query.getSelect(), symbolMap.asMap());
+ ExpressionMappingVisitor.mapExpressions(query.getHaving(), symbolMap.asMap());
+
+ if (!CapabilitiesUtil.supports(Capability.QUERY_FUNCTIONS_IN_GROUP_BY, modelID, metadata, capFinder)) {
+ //if group by expressions are not support, add an inline view to compensate
+ query = RuleCollapseSource.rewriteGroupByExpressionsAsView(query, metadata);
+ }
+ }
return query;
}
@@ -273,7 +295,7 @@
for (ElementSymbol element : elements) {
if(metadata.elementSupports(element.getMetadataID(), SupportConstants.Element.SELECT)) {
- element = (ElementSymbol)element.clone();
+ element = element.clone();
element.setGroupSymbol(group);
return element;
}
@@ -323,10 +345,10 @@
// Get last two clauses added to the FROM and combine them into a JoinPredicate
From from = query.getFrom();
- List clauses = from.getClauses();
+ List<FromClause> clauses = from.getClauses();
int lastClause = clauses.size()-1;
- FromClause clause1 = (FromClause) clauses.get(lastClause-1);
- FromClause clause2 = (FromClause) clauses.get(lastClause);
+ FromClause clause1 = clauses.get(lastClause-1);
+ FromClause clause2 = clauses.get(lastClause);
//correct the criteria or the join type if necessary
if (joinType != JoinType.JOIN_CROSS && crits.isEmpty()) {
@@ -492,13 +514,13 @@
*/
private void simplifyFromClause(Query query) {
From from = query.getFrom();
- List clauses = from.getClauses();
- FromClause rootClause = (FromClause) clauses.get(0);
+ List<FromClause> clauses = from.getClauses();
+ FromClause rootClause = clauses.get(0);
// If all joins are inner joins, move criteria to WHERE and make
// FROM a list of groups instead of a tree of JoinPredicates
if(! hasOuterJoins(rootClause)) {
- from.setClauses(new ArrayList());
+ from.setClauses(new ArrayList<FromClause>());
shredJoinTree(rootClause, query);
} // else leave as is
}
@@ -554,4 +576,75 @@
return "CollapseSource"; //$NON-NLS-1$
}
+ public static Query rewriteGroupByExpressionsAsView(Query query, QueryMetadataInterface metadata) {
+ if (query.getGroupBy() == null) {
+ return query;
+ }
+ // we check for group by expressions here to create an ANSI SQL plan
+ boolean hasExpression = false;
+ for (final Iterator<Expression> iterator = query.getGroupBy().getSymbols().iterator(); !hasExpression && iterator.hasNext();) {
+ hasExpression = !(iterator.next() instanceof ElementSymbol);
+ }
+ if (!hasExpression) {
+ return query;
+ }
+ Select select = query.getSelect();
+ GroupBy groupBy = query.getGroupBy();
+ query.setGroupBy(null);
+ Criteria having = query.getHaving();
+ query.setHaving(null);
+ OrderBy orderBy = query.getOrderBy();
+ query.setOrderBy(null);
+ Limit limit = query.getLimit();
+ query.setLimit(null);
+ Set<Expression> newSelectColumns = new HashSet<Expression>();
+ for (final Iterator<Expression> iterator = groupBy.getSymbols().iterator(); iterator.hasNext();) {
+ newSelectColumns.add(iterator.next());
+ }
+ Set<AggregateSymbol> aggs = new HashSet<AggregateSymbol>();
+ aggs.addAll(AggregateSymbolCollectorVisitor.getAggregates(select, true));
+ if (having != null) {
+ aggs.addAll(AggregateSymbolCollectorVisitor.getAggregates(having, true));
+ }
+ for (AggregateSymbol aggregateSymbol : aggs) {
+ if (aggregateSymbol.getExpression() != null) {
+ Expression expr = aggregateSymbol.getExpression();
+ newSelectColumns.add(SymbolMap.getExpression(expr));
+ }
+ }
+ Select innerSelect = new Select();
+ int index = 0;
+ for (Expression expr : newSelectColumns) {
+ if (expr instanceof SingleElementSymbol) {
+ innerSelect.addSymbol((SingleElementSymbol)expr);
+ } else {
+ innerSelect.addSymbol(new ExpressionSymbol("EXPR" + index++ , expr)); //$NON-NLS-1$
+ }
+ }
+ query.setSelect(innerSelect);
+ Query outerQuery = null;
+ try {
+ outerQuery = QueryRewriter.createInlineViewQuery(new GroupSymbol("X"), query, metadata, query.getSelect().getProjectedSymbols()); //$NON-NLS-1$
+ } catch (TeiidException err) {
+ throw new TeiidRuntimeException(err);
+ }
+ Iterator<SingleElementSymbol> iter = outerQuery.getSelect().getProjectedSymbols().iterator();
+ HashMap<Expression, SingleElementSymbol> expressionMap = new HashMap<Expression, SingleElementSymbol>();
+ for (SingleElementSymbol symbol : query.getSelect().getProjectedSymbols()) {
+ expressionMap.put(SymbolMap.getExpression(symbol), iter.next());
+ }
+ ExpressionMappingVisitor.mapExpressions(groupBy, expressionMap);
+ outerQuery.setGroupBy(groupBy);
+ ExpressionMappingVisitor.mapExpressions(having, expressionMap);
+ outerQuery.setHaving(having);
+ ExpressionMappingVisitor.mapExpressions(orderBy, expressionMap);
+ outerQuery.setOrderBy(orderBy);
+ outerQuery.setLimit(limit);
+ ExpressionMappingVisitor.mapExpressions(select, expressionMap);
+ outerQuery.setSelect(select);
+ outerQuery.setOption(query.getOption());
+ query = outerQuery;
+ return query;
+ }
+
}
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleConstants.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleConstants.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleConstants.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -34,7 +34,6 @@
public static final OptimizerRule MERGE_VIRTUAL = new RuleMergeVirtual();
public static final OptimizerRule CHOOSE_JOIN_STRATEGY = new RuleChooseJoinStrategy();
public static final OptimizerRule RAISE_ACCESS = new RuleRaiseAccess();
- public static final OptimizerRule PUSH_AGGREGATES = new RulePushAggregates();
public static final OptimizerRule CHOOSE_DEPENDENT = new RuleChooseDependent();
public static final OptimizerRule COLLAPSE_SOURCE = new RuleCollapseSource();
public static final OptimizerRule ASSIGN_OUTPUT_ELEMENTS = new RuleAssignOutputElements();
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleDecomposeJoin.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleDecomposeJoin.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleDecomposeJoin.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -25,7 +25,6 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
@@ -208,20 +207,15 @@
throws TeiidComponentException, QueryPlannerException,
QueryMetadataException {
Set<String> groups = context.getGroups();
- if (groups == null) {
- groups = new HashSet<String>();
- context.setGroups(groups);
- }
group = RulePlaceAccess.recontextSymbol(group, groups);
PlanNode projectNode = NodeEditor.findNodePreOrder(newUnion, NodeConstants.Types.PROJECT);
List<? extends SingleElementSymbol> projectedSymbols = (List<? extends SingleElementSymbol>)projectNode.getProperty(Info.PROJECT_COLS);
- PlanNode view = RulePushAggregates.createView(group, projectedSymbols, newUnion, metadata);
+ SymbolMap newSymbolMap = RulePushAggregates.createSymbolMap(group, projectedSymbols, newUnion, metadata);
+ PlanNode view = RuleDecomposeJoin.createSource(group, newUnion, newSymbolMap);
- SymbolMap newSymbolMap = (SymbolMap)view.getProperty(Info.SYMBOL_MAP);
-
Map<Expression, ElementSymbol> inverseMap = newSymbolMap.inserseMapping();
toReplace.getParent().replaceChild(toReplace, view);
Set<GroupSymbol> newGroups = Collections.singleton(group);
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleMergeCriteria.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleMergeCriteria.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleMergeCriteria.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -591,7 +591,7 @@
boolean distinct = false;
if (query.getGroupBy() != null) {
distinct = true;
- for (SingleElementSymbol groupByExpr : (List<SingleElementSymbol>)query.getGroupBy().getSymbols()) {
+ for (Expression groupByExpr : query.getGroupBy().getSymbols()) {
if (!expressions.contains(groupByExpr)) {
distinct = false;
break;
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-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleMergeVirtual.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -41,6 +41,7 @@
import org.teiid.query.optimizer.relational.plantree.NodeEditor;
import org.teiid.query.optimizer.relational.plantree.PlanNode;
import org.teiid.query.optimizer.relational.plantree.NodeConstants.Info;
+import org.teiid.query.resolver.util.AccessPattern;
import org.teiid.query.sql.lang.JoinType;
import org.teiid.query.sql.lang.OrderBy;
import org.teiid.query.sql.lang.OrderByItem;
@@ -161,13 +162,7 @@
return root;
}
- PlanNode parentGroup = NodeEditor.findParent(frame, NodeConstants.Types.GROUP, NodeConstants.Types.SOURCE);
- List<SingleElementSymbol> groupCols = null;
- if (parentGroup != null) {
- groupCols = (List<SingleElementSymbol>)parentGroup.getProperty(NodeConstants.Info.GROUP_COLS);
- }
-
- if (!checkProjectedSymbols(projectNode, virtualGroup, parentJoin, groupCols, symbolMap, metadata)) {
+ if (!checkProjectedSymbols(projectNode, virtualGroup, parentJoin, metadata)) {
return root;
}
@@ -190,9 +185,9 @@
// find the new root of the frame so that access patterns can be propagated
PlanNode newRoot = FrameUtil.findJoinSourceNode(frame.getFirstChild());
if (newRoot != null) {
- Collection ap = (Collection)frame.getProperty(NodeConstants.Info.ACCESS_PATTERNS);
+ Collection<AccessPattern> ap = (Collection)frame.getProperty(NodeConstants.Info.ACCESS_PATTERNS);
if (ap != null) {
- Collection newAp = (Collection)newRoot.getProperty(NodeConstants.Info.ACCESS_PATTERNS);
+ Collection<AccessPattern> newAp = (Collection)newRoot.getProperty(NodeConstants.Info.ACCESS_PATTERNS);
if (newAp == null) {
newRoot.setProperty(NodeConstants.Info.ACCESS_PATTERNS, ap);
} else {
@@ -323,8 +318,6 @@
private static boolean checkProjectedSymbols(PlanNode projectNode,
GroupSymbol virtualGroup,
PlanNode parentJoin,
- List<SingleElementSymbol> parentGroupingCols,
- SymbolMap symbolMap,
QueryMetadataInterface metadata) {
List<SingleElementSymbol> selectSymbols = (List<SingleElementSymbol>)projectNode.getProperty(NodeConstants.Info.PROJECT_COLS);
@@ -351,7 +344,6 @@
}
}
- List<ElementSymbol> virtualElements = symbolMap.getKeys();
for (int i = 0; i < selectSymbols.size(); i++) {
SingleElementSymbol symbol = selectSymbols.get(i);
Collection scalarSubqueries = ValueIteratorProviderCollectorVisitor.getValueIteratorProviders(symbol);
@@ -361,9 +353,6 @@
if (checkForNullDependent && JoinUtil.isNullDependent(metadata, groups, SymbolMap.getExpression(symbol))) {
return false;
}
- if (parentGroupingCols != null && !(SymbolMap.getExpression(symbol) instanceof SingleElementSymbol) && parentGroupingCols.contains(virtualElements.get(i))) {
- return false;
- }
// TEIID-16: We do not want to merge a non-deterministic scalar function
if (FunctionCollectorVisitor.isNonDeterministic(symbol)) {
return false;
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RulePlaceAccess.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RulePlaceAccess.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RulePlaceAccess.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -69,10 +69,6 @@
QueryPlannerException {
Set<String> groups = context.getGroups();
- if (groups == null) {
- groups = new HashSet<String>();
- context.setGroups(groups);
- }
boolean[] addtionalRules = new boolean[2];
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RulePlanSorts.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RulePlanSorts.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RulePlanSorts.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -22,6 +22,7 @@
package org.teiid.query.optimizer.relational.rules;
+import java.util.ArrayList;
import java.util.List;
import org.teiid.api.exception.query.QueryMetadataException;
@@ -43,8 +44,11 @@
import org.teiid.query.sql.lang.SetQuery;
import org.teiid.query.sql.symbol.AggregateSymbol;
import org.teiid.query.sql.symbol.AliasSymbol;
+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.SingleElementSymbol;
+import org.teiid.query.sql.util.SymbolMap;
import org.teiid.query.util.CommandContext;
@@ -86,13 +90,25 @@
root = checkForProjectOptimization(node, root, metadata, capFinder, record);
}
List<SingleElementSymbol> orderColumns = ((OrderBy)node.getProperty(NodeConstants.Info.SORT_ORDER)).getSortKeys();
+ List<Expression> sortExpressions = new ArrayList<Expression>(orderColumns.size());
PlanNode possibleSort = NodeEditor.findNodePreOrder(node, NodeConstants.Types.GROUP, NodeConstants.Types.SOURCE | NodeConstants.Types.ACCESS);
if (possibleSort != null) {
- List exprs = (List)possibleSort.getProperty(Info.GROUP_COLS);
- if (exprs != null && exprs.containsAll(orderColumns)) {
- exprs.removeAll(orderColumns);
- orderColumns.addAll(exprs);
- possibleSort.setProperty(Info.GROUP_COLS, orderColumns);
+ boolean otherExpression = false;
+ SymbolMap groupMap = (SymbolMap)possibleSort.getProperty(Info.SYMBOL_MAP);
+ for (SingleElementSymbol singleElementSymbol : orderColumns) {
+ Expression ex = SymbolMap.getExpression(singleElementSymbol);
+ if (ex instanceof ElementSymbol) {
+ sortExpressions.add(groupMap.getMappedExpression((ElementSymbol) ex));
+ } else {
+ otherExpression = true;
+ break;
+ }
+ }
+
+ List<Expression> exprs = (List<Expression>)possibleSort.getProperty(Info.GROUP_COLS);
+ if (!otherExpression && exprs != null && exprs.containsAll(sortExpressions)) {
+ exprs.removeAll(sortExpressions);
+ exprs.addAll(0, sortExpressions);
if (node.getParent() == null) {
root = node.getFirstChild();
root.removeFromParent();
@@ -105,54 +121,6 @@
}
break;
}
-/* possibleSort = NodeEditor.findNodePreOrder(node, NodeConstants.Types.JOIN, NodeConstants.Types.SOURCE | NodeConstants.Types.ACCESS);
- if (possibleSort == null) {
- break;
- }
- boolean left = false;
- if (possibleSort.getType() == NodeConstants.Types.JOIN) {
- if (possibleSort.getProperty(NodeConstants.Info.JOIN_STRATEGY) != JoinStrategyType.MERGE
- || possibleSort.getProperty(NodeConstants.Info.JOIN_TYPE) != JoinType.JOIN_INNER) {
- break;
- }
- if (FrameUtil.findJoinSourceNode(possibleSort.getFirstChild()).getGroups().containsAll(node.getGroups())
- && possibleSort.getProperty(NodeConstants.Info.SORT_LEFT) == SortOption.SORT) {
- left = true;
- } else if (!FrameUtil.findJoinSourceNode(possibleSort.getLastChild()).getGroups().containsAll(node.getGroups())
- || possibleSort.getProperty(NodeConstants.Info.SORT_RIGHT) != SortOption.SORT) {
- break;
- }
- }
- List exprs = (List)possibleSort.getProperty(left?Info.LEFT_EXPRESSIONS:Info.RIGHT_EXPRESSIONS);
- if (exprs != null && exprs.containsAll(orderColumns)) {
- List<Integer> indexes = new ArrayList<Integer>(orderColumns.size());
- for (Expression expr : (List<Expression>)orderColumns) {
- indexes.add(0, exprs.indexOf(expr));
- }
- exprs.removeAll(orderColumns);
- List newExprs = new ArrayList(orderColumns);
- newExprs.addAll(exprs);
- possibleSort.setProperty(left?Info.LEFT_EXPRESSIONS:Info.RIGHT_EXPRESSIONS, newExprs);
- if (node.getParent() == null) {
- root = node.getFirstChild();
- root.removeFromParent();
- node = root;
- } else {
- PlanNode nextNode = node.getFirstChild();
- NodeEditor.removeChildNode(node.getParent(), node);
- node = nextNode;
- }
- exprs = (List)possibleSort.getProperty(left?Info.RIGHT_EXPRESSIONS:Info.LEFT_EXPRESSIONS);
- List toRemove = new ArrayList();
- for (Integer index : indexes) {
- Object o = exprs.get(index);
- exprs.add(0, o);
- toRemove.add(o);
- }
- exprs.subList(indexes.size(), exprs.size()).removeAll(toRemove);
- possibleSort.setProperty(left?NodeConstants.Info.SORT_LEFT:NodeConstants.Info.SORT_RIGHT, SortOption.SORT_REQUIRED);
- }
-*/
break;
case NodeConstants.Types.DUP_REMOVE:
if (parentBlocking) {
@@ -243,13 +211,8 @@
if(ss instanceof AliasSymbol) {
ss = ((AliasSymbol)ss).getSymbol();
}
-
if (ss instanceof ExpressionSymbol && !(ss instanceof AggregateSymbol)) {
- ExpressionSymbol exprSymbol = (ExpressionSymbol)ss;
-
- if (!exprSymbol.isDerivedExpression()) {
- return root; //TODO: insert a new project node to handle this case
- }
+ return root; //TODO: insert a new project node to handle this case
}
if (!childOutputCols.contains(ss)) {
return root;
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RulePushAggregates.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RulePushAggregates.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RulePushAggregates.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -40,17 +40,18 @@
import org.teiid.api.exception.query.QueryPlannerException;
import org.teiid.api.exception.query.QueryResolverException;
import org.teiid.core.TeiidComponentException;
+import org.teiid.core.id.IDGenerator;
import org.teiid.core.types.DataTypeManager;
import org.teiid.language.SQLConstants.NonReserved;
import org.teiid.query.analysis.AnalysisRecord;
import org.teiid.query.function.FunctionLibrary;
import org.teiid.query.metadata.QueryMetadataInterface;
import org.teiid.query.metadata.TempMetadataAdapter;
-import org.teiid.query.metadata.TempMetadataID;
import org.teiid.query.metadata.TempMetadataStore;
import org.teiid.query.optimizer.capabilities.CapabilitiesFinder;
import org.teiid.query.optimizer.capabilities.SourceCapabilities.Capability;
import org.teiid.query.optimizer.relational.OptimizerRule;
+import org.teiid.query.optimizer.relational.RelationalPlanner;
import org.teiid.query.optimizer.relational.RuleStack;
import org.teiid.query.optimizer.relational.plantree.NodeConstants;
import org.teiid.query.optimizer.relational.plantree.NodeEditor;
@@ -61,7 +62,6 @@
import org.teiid.query.resolver.util.ResolverVisitor;
import org.teiid.query.rewriter.QueryRewriter;
import org.teiid.query.sql.LanguageObject;
-import org.teiid.query.sql.LanguageObject.Util;
import org.teiid.query.sql.lang.CompareCriteria;
import org.teiid.query.sql.lang.Criteria;
import org.teiid.query.sql.lang.IsNullCriteria;
@@ -94,6 +94,12 @@
*/
public class RulePushAggregates implements
OptimizerRule {
+
+ private IDGenerator idGenerator;
+
+ public RulePushAggregates(IDGenerator idGenerator) {
+ this.idGenerator = idGenerator;
+ }
/**
* @see org.teiid.query.optimizer.relational.OptimizerRule#execute(org.teiid.query.optimizer.relational.plantree.PlanNode,
@@ -113,13 +119,16 @@
for (PlanNode groupNode : NodeEditor.findAllNodes(plan, NodeConstants.Types.GROUP, NodeConstants.Types.ACCESS)) {
PlanNode child = groupNode.getFirstChild();
- List<SingleElementSymbol> groupingExpressions = (List<SingleElementSymbol>)groupNode.getProperty(NodeConstants.Info.GROUP_COLS);
+ List<Expression> groupingExpressions = (List<Expression>)groupNode.getProperty(NodeConstants.Info.GROUP_COLS);
+ if (groupingExpressions == null) {
+ groupingExpressions = Collections.emptyList();
+ }
if (child.getType() == NodeConstants.Types.SOURCE) {
PlanNode setOp = child.getFirstChild();
try {
- pushGroupNodeOverUnion(plan, metadata, capFinder, groupNode, child, groupingExpressions, setOp, context, analysisRecord);
+ pushGroupNodeOverUnion(metadata, capFinder, groupNode, child, groupingExpressions, setOp, context, analysisRecord);
} catch (QueryResolverException e) {
throw new TeiidComponentException(e);
}
@@ -132,7 +141,7 @@
Set<AggregateSymbol> aggregates = collectAggregates(groupNode);
- pushGroupNode(groupNode, groupingExpressions, aggregates, metadata, capFinder);
+ pushGroupNode(groupNode, groupingExpressions, aggregates, metadata, capFinder, context);
}
return plan;
@@ -159,48 +168,16 @@
* ...
*
* Or if the child does not support pushdown we add dummy aggregate projection
- * count(*) = 1, count(x) = case x is null then 0 else 1 end, avg(x) = x, etc.
- *
- * if partitioned, then we don't need decomposition or the top level group by
- *
- * source
- * set op
- * project
- * [select]
- * group [agg(x), {a, b}]
- * source
- * child 1
- * ...
- *
+ * count(*) = 1, count(x) = case x is null then 0 else 1 end, avg(x) = x, etc.
*/
- private void pushGroupNodeOverUnion(PlanNode plan,
- QueryMetadataInterface metadata, CapabilitiesFinder capFinder,
+ private void pushGroupNodeOverUnion(QueryMetadataInterface metadata, CapabilitiesFinder capFinder,
PlanNode groupNode, PlanNode unionSourceParent,
- List<SingleElementSymbol> groupingExpressions, PlanNode setOp, CommandContext context, AnalysisRecord record)
+ List<Expression> groupingExpressions, PlanNode setOp, CommandContext context, AnalysisRecord record)
throws TeiidComponentException, QueryMetadataException,
QueryPlannerException, QueryResolverException {
- if (setOp == null) {
+ if (setOp == null || setOp.getProperty(NodeConstants.Info.SET_OPERATION) != Operation.UNION) {
return;
}
- PlanNode intermediateView = null;
- if (setOp.getType() != NodeConstants.Types.SET_OP) {
- if (setOp.getType() != NodeConstants.Types.PROJECT) {
- return;
- }
- intermediateView = unionSourceParent;
- unionSourceParent = setOp.getFirstChild();
- if (unionSourceParent == null || unionSourceParent.getType() != NodeConstants.Types.SOURCE || unionSourceParent.getFirstChild() == null
- || unionSourceParent.getFirstChild().getType() != NodeConstants.Types.SET_OP || unionSourceParent.getFirstChild().getProperty(NodeConstants.Info.SET_OPERATION) != Operation.UNION) {
- return; //not an eligible union
- }
- setOp = unionSourceParent.getFirstChild();
- if (groupingExpressions == null) {
- return; //shouldn't happen - the view should have been removed
- }
- }
- if (setOp.getProperty(NodeConstants.Info.SET_OPERATION) != Operation.UNION) {
- return;
- }
LinkedHashSet<AggregateSymbol> aggregates = collectAggregates(groupNode);
Map<ElementSymbol, List<Set<Constant>>> partitionInfo = (Map<ElementSymbol, List<Set<Constant>>>)unionSourceParent.getProperty(Info.PARTITION_INFO);
@@ -212,33 +189,10 @@
findUnionChildren(unionChildren, cardinalityDependent, setOp);
SymbolMap parentMap = (SymbolMap)unionSourceParent.getProperty(NodeConstants.Info.SYMBOL_MAP);
- List<ElementSymbol> virtualElements = parentMap.getKeys();
- GroupSymbol virtualGroup = unionSourceParent.getGroups().iterator().next();
- List<SingleElementSymbol> actualGroupingExpressions = groupingExpressions;
- if (intermediateView != null) {
- actualGroupingExpressions = new ArrayList<SingleElementSymbol>(groupingExpressions.size());
- SymbolMap viewMap = (SymbolMap)intermediateView.getProperty(NodeConstants.Info.SYMBOL_MAP);
- for (SingleElementSymbol ses : groupingExpressions) {
- Expression ex = viewMap.getMappedExpression((ElementSymbol)ses);
- SingleElementSymbol newCol = null;
- if (ex instanceof SingleElementSymbol) {
- newCol = (SingleElementSymbol)ex;
- } else {
- newCol = new ExpressionSymbol("grouping", ex); //$NON-NLS-1$
- }
- actualGroupingExpressions.add(newCol);
- }
- }
-
//partitioned union
- if (partitionInfo != null && !Collections.disjoint(partitionInfo.keySet(), actualGroupingExpressions)) {
- if (intermediateView != null) {
- parentMap = pushGroupByView(plan, metadata, capFinder, unionSourceParent,
- setOp, intermediateView, cardinalityDependent,
- unionChildren, virtualElements, virtualGroup);
- }
- decomposeGroupBy(groupNode, unionSourceParent, groupingExpressions, aggregates, unionChildren, parentMap, metadata, capFinder, intermediateView != null);
+ if (partitionInfo != null && !Collections.disjoint(partitionInfo.keySet(), groupingExpressions)) {
+ decomposeGroupBy(groupNode, unionSourceParent, groupingExpressions, aggregates, unionChildren, parentMap, metadata, capFinder, context);
return;
}
@@ -248,10 +202,15 @@
* serves as a hint to distribute a distinct to the union queries
*/
if (aggregates.isEmpty()) {
- if (groupingExpressions != null && !groupingExpressions.isEmpty()) {
+ if (!groupingExpressions.isEmpty()) {
setOp.setProperty(NodeConstants.Info.USE_ALL, Boolean.FALSE);
}
return;
+ }
+ for (AggregateSymbol agg : aggregates) {
+ if (!agg.canStage()) {
+ return;
+ }
}
//TODO: merge virtual, plan unions, raise null - change the partition information
@@ -263,12 +222,12 @@
List<SingleElementSymbol> copy = new ArrayList<SingleElementSymbol>(aggregates);
aggregates.clear();
Map<AggregateSymbol, Expression> aggMap = buildAggregateMap(copy, metadata, aggregates);
-
+
boolean shouldPushdown = false;
List<Boolean> pushdownList = new ArrayList<Boolean>(unionChildren.size());
for (PlanNode planNode : unionChildren) {
- boolean pushdown = canPushGroupByToUnionChild(metadata, capFinder, actualGroupingExpressions, aggregates, planNode, record);
+ boolean pushdown = canPushGroupByToUnionChild(metadata, capFinder, groupingExpressions, aggregates, planNode, record);
pushdownList.add(pushdown);
shouldPushdown |= pushdown;
}
@@ -277,140 +236,238 @@
return;
}
- if (intermediateView != null) {
- parentMap = pushGroupByView(plan, metadata, capFinder, unionSourceParent,
- setOp, intermediateView, cardinalityDependent,
- unionChildren, virtualElements, virtualGroup);
- virtualElements = parentMap.getKeys();
- virtualGroup = unionSourceParent.getGroups().iterator().next();
- }
+ GroupSymbol group = unionSourceParent.getGroups().iterator().next().clone();
Iterator<Boolean> pushdownIterator = pushdownList.iterator();
+ boolean first = true;
for (PlanNode planNode : unionChildren) {
- addView(plan, planNode, pushdownIterator.next(), new GroupSymbol("X"), groupingExpressions, aggregates, virtualElements, metadata, capFinder, null); //$NON-NLS-1$
+ addUnionGroupBy(groupingExpressions, aggregates, parentMap, metadata, capFinder, context, group, first, planNode, !pushdownIterator.next());
+ first = false;
}
- //update the parent plan with the staged aggregates and the new projected symbols
- List<SingleElementSymbol> projectedViewSymbols = (List<SingleElementSymbol>)NodeEditor.findNodePreOrder(unionSourceParent, NodeConstants.Types.PROJECT).getProperty(NodeConstants.Info.PROJECT_COLS);
+ updateParentAggs(groupNode, context, aggMap, metadata);
- //hack to introduce aggregate symbols to the parent view TODO: this should change the metadata properly.
- SymbolMap newParentMap = modifyUnionSourceParent(unionSourceParent, virtualGroup, projectedViewSymbols, virtualElements);
- Map<AggregateSymbol, ElementSymbol> projectedMap = new HashMap<AggregateSymbol, ElementSymbol>();
- Iterator<AggregateSymbol> aggIter = aggregates.iterator();
- for (ElementSymbol projectedViewSymbol : newParentMap.getKeys().subList(projectedViewSymbols.size() - aggregates.size(), projectedViewSymbols.size())) {
- projectedMap.put(aggIter.next(), projectedViewSymbol);
+ List<SingleElementSymbol> symbols = (List<SingleElementSymbol>) NodeEditor.findNodePreOrder(unionSourceParent, NodeConstants.Types.PROJECT).getProperty(Info.PROJECT_COLS);
+ GroupSymbol modifiedGroup = group.clone();
+ SymbolMap symbolMap = createSymbolMap(modifiedGroup, symbols, unionSourceParent, metadata);
+ unionSourceParent.setProperty(Info.SYMBOL_MAP, symbolMap);
+
+ //correct the parent frame
+ Map<Expression, ElementSymbol> mapping = new HashMap<Expression, ElementSymbol>();
+ Iterator<ElementSymbol> elemIter = symbolMap.getKeys().iterator();
+ for (Expression expr : groupingExpressions) {
+ mapping.put(expr, elemIter.next());
}
- for (Expression expr : aggMap.values()) {
- ExpressionMappingVisitor.mapExpressions(expr, projectedMap);
+ for (AggregateSymbol agg : aggregates) {
+ mapping.put(agg, elemIter.next());
}
- mapExpressions(groupNode.getParent(), aggMap, metadata);
- }
-
- private SymbolMap pushGroupByView(PlanNode plan,
- QueryMetadataInterface metadata, CapabilitiesFinder capFinder,
- PlanNode unionSourceParent, PlanNode setOp,
- PlanNode intermediateView, boolean cardinalityDependent,
- LinkedList<PlanNode> unionChildren,
- List<ElementSymbol> virtualElements, GroupSymbol virtualGroup)
- throws TeiidComponentException, QueryPlannerException,
- QueryResolverException {
- //perform view pushing
- /*
- * TODO: this introduces yet another potentially unneeded view, but cannot be removed by the normal merge virtual logic
- * due to an intervening access node
- */
- PlanNode intermediateProject = intermediateView.getFirstChild();
- List<SingleElementSymbol> projectedViewSymbols = (List<SingleElementSymbol>)intermediateProject.getProperty(NodeConstants.Info.PROJECT_COLS);
- for (PlanNode planNode : unionChildren) {
- addView(plan, planNode, false, virtualGroup.clone(), null, Collections.EMPTY_SET, virtualElements, metadata, capFinder, LanguageObject.Util.deepClone(projectedViewSymbols, SingleElementSymbol.class));
+ PlanNode node = unionSourceParent;
+ while (node != groupNode.getParent()) {
+ FrameUtil.convertNode(node, null, null, mapping, metadata, false);
+ node = node.getParent();
}
- unionChildren.clear();
- findUnionChildren(unionChildren, cardinalityDependent, setOp);
- virtualGroup = intermediateView.getGroups().iterator().next();
- unionSourceParent.getGroups().clear();
- unionSourceParent.addGroup(virtualGroup);
- projectedViewSymbols = (List<SingleElementSymbol>)NodeEditor.findNodePreOrder(unionSourceParent, NodeConstants.Types.PROJECT).getProperty(NodeConstants.Info.PROJECT_COLS);
- SymbolMap parentMap = modifyUnionSourceParent(unionSourceParent, virtualGroup, projectedViewSymbols, Collections.EMPTY_LIST);
- //remove the old view
- NodeEditor.removeChildNode(intermediateView, intermediateProject);
- NodeEditor.removeChildNode(intermediateView.getParent(), intermediateView);
- return parentMap;
}
- private SymbolMap modifyUnionSourceParent(PlanNode unionSourceParent,
- GroupSymbol virtualGroup,
- List<SingleElementSymbol> projectedViewSymbols, List<ElementSymbol> baseVirtualElements) {
- List<ElementSymbol> updatedVirturalElement = new ArrayList<ElementSymbol>(baseVirtualElements);
- for (int i = updatedVirturalElement.size(); i < projectedViewSymbols.size(); i++) {
- SingleElementSymbol symbol = projectedViewSymbols.get(i);
- String name = symbol.getShortName();
- String virtualElementName = virtualGroup.getCanonicalName() + ElementSymbol.SEPARATOR + name;
- ElementSymbol virtualElement = new ElementSymbol(virtualElementName);
- virtualElement.setGroupSymbol(virtualGroup);
- virtualElement.setType(symbol.getType());
- virtualElement.setMetadataID(new TempMetadataID(virtualElementName, symbol.getType()));
- updatedVirturalElement.add(virtualElement);
+ private void updateParentAggs(PlanNode groupNode, CommandContext context,
+ Map<AggregateSymbol, Expression> aggMap, QueryMetadataInterface metadata)
+ throws QueryMetadataException, TeiidComponentException, QueryPlannerException {
+ LinkedHashSet<AggregateSymbol> compositeAggs = new LinkedHashSet<AggregateSymbol>();
+ boolean hasExpressionMapping = false;
+ for (Expression ex : aggMap.values()) {
+ if (ex instanceof AggregateSymbol) {
+ compositeAggs.add((AggregateSymbol) ex);
+ } else {
+ AggregateSymbolCollectorVisitor.getAggregates(ex, compositeAggs, null);
+ hasExpressionMapping = true;
+ }
}
- SymbolMap newParentMap = SymbolMap.createSymbolMap(updatedVirturalElement, projectedViewSymbols);
- unionSourceParent.setProperty(NodeConstants.Info.SYMBOL_MAP, newParentMap);
- return newParentMap;
+ if (!hasExpressionMapping) {
+ //if no new expressions are created we can just modify the existing aggregates
+ FrameUtil.correctSymbolMap(aggMap, groupNode);
+ } else {
+ //if new expressions are created we insert a view to handle the projection
+ groupNode.getGroups().clear();
+ SymbolMap oldGroupingMap = (SymbolMap) groupNode.getProperty(Info.SYMBOL_MAP);
+ GroupSymbol oldGroup = oldGroupingMap.asMap().keySet().iterator().next().getGroupSymbol();
+ SymbolMap groupingMap = RelationalPlanner.buildGroupingNode(compositeAggs, (List<? extends Expression>) groupNode.getProperty(Info.GROUP_COLS), groupNode, context, idGenerator);
+ ArrayList<SingleElementSymbol> projectCols = new ArrayList<SingleElementSymbol>(oldGroupingMap.asMap().size());
+ SymbolMap correctedMap = new SymbolMap();
+ Map<Expression, ElementSymbol> inverseMap = groupingMap.inserseMapping();
+ for (Map.Entry<ElementSymbol, Expression> entry : oldGroupingMap.asMap().entrySet()) {
+ SingleElementSymbol ses = null;
+ if (entry.getValue() instanceof AggregateSymbol) {
+ Expression ex = aggMap.get(entry.getValue());
+ if (ex instanceof AggregateSymbol) {
+ ses = inverseMap.get(ex);
+ } else {
+ ExpressionMappingVisitor.mapExpressions(ex, inverseMap);
+ ses = new ExpressionSymbol("expr", ex); //$NON-NLS-1$
+ }
+ } else {
+ ses = inverseMap.get(entry.getValue());
+ }
+ ses = (SingleElementSymbol) ses.clone();
+ projectCols.add(new AliasSymbol(entry.getKey().getShortCanonicalName(), ses));
+ correctedMap.addMapping(entry.getKey(), SymbolMap.getExpression(ses));
+ }
+ PlanNode projectNode = groupNode.getParent();
+ if (projectNode.getType() != NodeConstants.Types.PROJECT) {
+ projectNode = NodeFactory.getNewNode(NodeConstants.Types.PROJECT);
+ groupNode.addAsParent(projectNode);
+ projectNode.setProperty(Info.PROJECT_COLS, projectCols);
+ RuleDecomposeJoin.createSource(oldGroup, projectNode, correctedMap);
+ } else {
+ FrameUtil.convertFrame(projectNode, oldGroup, null, correctedMap.asMap(), metadata);
+ }
+ }
}
+ /* if partitioned, then we don't need decomposition or the top level group by
+ *
+ * source
+ * set op
+ * project
+ * group [agg(x), {a, b}]
+ * source
+ * child 1
+ * ...
+ *
+ */
private void decomposeGroupBy(PlanNode groupNode, PlanNode sourceNode,
- List<SingleElementSymbol> groupingExpressions,
+ List<Expression> groupingExpressions,
LinkedHashSet<AggregateSymbol> aggregates,
LinkedList<PlanNode> unionChildren, SymbolMap parentMap, QueryMetadataInterface metadata,
- CapabilitiesFinder capFinder, boolean hadIntermediateView) throws QueryPlannerException, QueryMetadataException, TeiidComponentException {
+ CapabilitiesFinder capFinder, CommandContext cc) throws QueryPlannerException, QueryMetadataException, TeiidComponentException, QueryResolverException {
// remove the group node
groupNode.getParent().replaceChild(groupNode, groupNode.getFirstChild());
+
GroupSymbol group = sourceNode.getGroups().iterator().next().clone();
boolean first = true;
- List<SingleElementSymbol> symbols = null;
for (PlanNode planNode : unionChildren) {
- PlanNode groupClone = NodeFactory.getNewNode(NodeConstants.Types.GROUP);
- groupClone.setProperty(Info.GROUP_COLS, LanguageObject.Util.deepClone(groupingExpressions, SingleElementSymbol.class));
- groupClone.addGroups(groupNode.getGroups());
-
- PlanNode view = RuleDecomposeJoin.createSource(group, planNode, parentMap);
-
- view.addAsParent(groupClone);
-
- PlanNode projectPlanNode = NodeFactory.getNewNode(NodeConstants.Types.PROJECT);
-
- Select allSymbols = new Select(groupingExpressions);
- allSymbols.addSymbols(aggregates);
- if (first) {
- first = false;
- QueryRewriter.makeSelectUnique(allSymbols, false);
- symbols = allSymbols.getProjectedSymbols();
- }
- projectPlanNode.setProperty(NodeConstants.Info.PROJECT_COLS, allSymbols.getSymbols());
- projectPlanNode.addGroups(view.getGroups());
-
- groupClone.addAsParent(projectPlanNode);
-
- if (hadIntermediateView) {
- //drill down to the possible access node
- planNode = planNode.getFirstChild().getFirstChild();
- }
- if (planNode.getType() == NodeConstants.Types.ACCESS) {
- //TODO: temporarily remove the access node so that the inline view could be removed if possible
- while (RuleRaiseAccess.raiseAccessNode(planNode, planNode, metadata, capFinder, true, null) != null) {
- //continue to raise
- }
- }
+ addUnionGroupBy(groupingExpressions, aggregates,
+ parentMap, metadata, capFinder, cc, group, first,
+ planNode, false);
+ first = false;
}
+ List<SingleElementSymbol> symbols = (List<SingleElementSymbol>) NodeEditor.findNodePreOrder(sourceNode, NodeConstants.Types.PROJECT).getProperty(Info.PROJECT_COLS);
GroupSymbol modifiedGroup = group.clone();
SymbolMap symbolMap = createSymbolMap(modifiedGroup, symbols, sourceNode, metadata);
sourceNode.setProperty(Info.SYMBOL_MAP, symbolMap);
+
+ //map from the anon group to the updated inline view group
+ SymbolMap map = (SymbolMap)groupNode.getProperty(Info.SYMBOL_MAP);
+ Map<Expression, ElementSymbol> inverse = map.inserseMapping();
+ SymbolMap newMapping = (SymbolMap) NodeEditor.findNodePreOrder(sourceNode, NodeConstants.Types.GROUP).getProperty(Info.SYMBOL_MAP);
- FrameUtil.convertFrame(sourceNode, group, Collections.singleton(modifiedGroup), symbolMap.inserseMapping(), metadata);
+ GroupSymbol oldGroup = null;
+ Map<ElementSymbol, ElementSymbol> updatedMapping = new HashMap<ElementSymbol, ElementSymbol>();
+ for (Map.Entry<ElementSymbol, Expression> entry : symbolMap.asMap().entrySet()) {
+ Expression ex = newMapping.getMappedExpression((ElementSymbol) entry.getValue());
+ ElementSymbol orig = inverse.get(ex);
+ oldGroup = orig.getGroupSymbol();
+ updatedMapping.put(orig, entry.getKey());
+ }
+ FrameUtil.convertFrame(sourceNode, oldGroup, Collections.singleton(modifiedGroup), updatedMapping, metadata);
}
+ private void addUnionGroupBy(
+ List<Expression> groupingExpressions,
+ LinkedHashSet<AggregateSymbol> aggregates, SymbolMap parentMap,
+ QueryMetadataInterface metadata, CapabilitiesFinder capFinder,
+ CommandContext cc, GroupSymbol group, boolean first, PlanNode planNode, boolean viewOnly)
+ throws QueryMetadataException, TeiidComponentException,
+ QueryPlannerException, QueryResolverException {
+ List<Expression> groupingColumns = LanguageObject.Util.deepClone(groupingExpressions, Expression.class);
+
+ //branches other than the first need to have their projected column names updated
+ if (!first) {
+ PlanNode sortNode = NodeEditor.findNodePreOrder(planNode, NodeConstants.Types.SORT, NodeConstants.Types.SOURCE);
+ List<SingleElementSymbol> sortOrder = null;
+ OrderBy orderBy = null;
+ if (sortNode != null) {
+ orderBy = (OrderBy)sortNode.getProperty(Info.SORT_ORDER);
+ sortOrder = orderBy.getSortKeys();
+ }
+ List<SingleElementSymbol> projectCols = FrameUtil.findTopCols(planNode);
+ List<ElementSymbol> virtualElements = parentMap.getKeys();
+ for (int i = 0; i < virtualElements.size(); i++) {
+ ElementSymbol virtualElem = virtualElements.get(i);
+ SingleElementSymbol projectedSymbol = projectCols.get(i);
+ if (!projectedSymbol.getShortCanonicalName().equals(virtualElem.getShortCanonicalName())) {
+ if (sortOrder != null) {
+ int sortIndex = sortOrder.indexOf(projectedSymbol);
+ if (sortIndex > -1) {
+ updateSymbolName(sortOrder, sortIndex, virtualElem, sortOrder.get(sortIndex));
+ orderBy.getOrderByItems().get(sortIndex).setSymbol(sortOrder.get(sortIndex));
+ }
+ }
+ updateSymbolName(projectCols, i, virtualElem, projectedSymbol);
+ }
+ }
+ }
+
+ PlanNode view = RuleDecomposeJoin.createSource(group, planNode, parentMap);
+
+ PlanNode projectPlanNode = NodeFactory.getNewNode(NodeConstants.Types.PROJECT);
+
+ Select allSymbols = new Select();
+ for (Expression expr : groupingColumns) {
+ allSymbols.addSymbol(new ExpressionSymbol("expr", expr)); //$NON-NLS-1$
+ }
+ if (viewOnly) {
+ for (AggregateSymbol agg : aggregates) {
+ agg = (AggregateSymbol)agg.clone();
+ if (agg.getAggregateFunction() == Type.COUNT) {
+ if (agg.getExpression() == null) {
+ allSymbols.addSymbol(new ExpressionSymbol("stagedAgg", new Constant(1))); //$NON-NLS-1$
+ } else {
+ SearchedCaseExpression count = new SearchedCaseExpression(Arrays.asList(new IsNullCriteria(agg.getExpression())), Arrays.asList(new Constant(Integer.valueOf(0))));
+ count.setElseExpression(new Constant(Integer.valueOf(1)));
+ count.setType(DataTypeManager.DefaultDataClasses.INTEGER);
+ allSymbols.addSymbol(new ExpressionSymbol("stagedAgg", count)); //$NON-NLS-1$
+ }
+ } else { //min, max, sum
+ Expression ex = agg.getExpression();
+ ex = ResolverUtil.convertExpression(ex, DataTypeManager.getDataTypeName(agg.getType()), metadata);
+ allSymbols.addSymbol(new ExpressionSymbol("stagedAgg", ex)); //$NON-NLS-1$
+ }
+ }
+ } else {
+ allSymbols.addSymbols(aggregates);
+ }
+ if (first) {
+ QueryRewriter.makeSelectUnique(allSymbols, false);
+ }
+ projectPlanNode.setProperty(NodeConstants.Info.PROJECT_COLS, allSymbols.getSymbols());
+ projectPlanNode.addGroups(view.getGroups());
+
+ view.addAsParent(projectPlanNode);
+
+ if (!viewOnly) {
+ addGroupBy(cc, view, groupingColumns, aggregates, metadata, projectPlanNode.getParent());
+ }
+
+ if (planNode.getType() == NodeConstants.Types.ACCESS) {
+ //TODO: temporarily remove the access node so that the inline view could be removed if possible
+ while (RuleRaiseAccess.raiseAccessNode(planNode, planNode, metadata, capFinder, true, null) != null) {
+ //continue to raise
+ }
+ }
+ }
+
+ private void updateSymbolName(List<SingleElementSymbol> projectCols, int i,
+ ElementSymbol virtualElem, SingleElementSymbol projectedSymbol) {
+ if (projectedSymbol instanceof AliasSymbol) {
+ ((AliasSymbol)projectedSymbol).setShortName(virtualElem.getShortCanonicalName());
+ } else {
+ projectCols.set(i, new AliasSymbol(virtualElem.getShortCanonicalName(), projectedSymbol));
+ }
+ }
+
private boolean canPushGroupByToUnionChild(QueryMetadataInterface metadata,
CapabilitiesFinder capFinder,
- List<SingleElementSymbol> groupingExpressions,
+ List<Expression> groupingExpressions,
LinkedHashSet<AggregateSymbol> aggregates, PlanNode planNode, AnalysisRecord record)
throws QueryMetadataException, TeiidComponentException {
if (planNode.getType() != NodeConstants.Types.ACCESS) {
@@ -422,16 +479,16 @@
return false;
}
for (AggregateSymbol aggregate : aggregates) {
- if (!CapabilitiesUtil.supportsAggregateFunction(modelId, aggregate, metadata, capFinder)) {
- return false;
- }
+ if(! CriteriaCapabilityValidatorVisitor.canPushLanguageObject(aggregate, modelId, metadata, capFinder, record)) {
+ return false;
+ }
}
- if ((groupingExpressions == null || groupingExpressions.isEmpty())) {
+ if (groupingExpressions.isEmpty()) {
if (!CapabilitiesUtil.supports(Capability.QUERY_AGGREGATES_COUNT_STAR, modelId, metadata, capFinder)) {
return false;
}
} else {
- for (SingleElementSymbol ses : groupingExpressions) {
+ for (Expression ses : groupingExpressions) {
if(! CriteriaCapabilityValidatorVisitor.canPushLanguageObject(ses, modelId, metadata, capFinder, record)) {
return false;
}
@@ -466,109 +523,7 @@
return null;
}
- public void addView(PlanNode root, PlanNode unionSource, boolean pushdown, GroupSymbol group, List<SingleElementSymbol> groupingExpressions,
- Set<AggregateSymbol> aggregates, List<ElementSymbol> virtualElements,
- QueryMetadataInterface metadata, CapabilitiesFinder capFinder, List<SingleElementSymbol> actualProject)
- throws TeiidComponentException, QueryPlannerException, QueryResolverException {
- PlanNode accessNode = null;
- if (pushdown) {
- accessNode = NodeEditor.findNodePreOrder(unionSource, NodeConstants.Types.ACCESS);
- }
- //branches other than the first need to have their projected column names updated
- PlanNode sortNode = NodeEditor.findNodePreOrder(unionSource, NodeConstants.Types.SORT, NodeConstants.Types.SOURCE);
- List<SingleElementSymbol> sortOrder = null;
- OrderBy orderBy = null;
- if (sortNode != null) {
- orderBy = (OrderBy)sortNode.getProperty(Info.SORT_ORDER);
- sortOrder = orderBy.getSortKeys();
- }
- List<SingleElementSymbol> projectCols = FrameUtil.findTopCols(unionSource);
- for (int i = 0; i < virtualElements.size(); i++) {
- ElementSymbol virtualElem = virtualElements.get(i);
- SingleElementSymbol projectedSymbol = projectCols.get(i);
- if (!projectedSymbol.getShortCanonicalName().equals(virtualElem.getShortCanonicalName())) {
- if (sortOrder != null) {
- int sortIndex = sortOrder.indexOf(projectedSymbol);
- if (sortIndex > -1) {
- updateSymbolName(sortOrder, sortIndex, virtualElem, sortOrder.get(sortIndex));
- orderBy.getOrderByItems().get(sortIndex).setSymbol(sortOrder.get(sortIndex));
- }
- }
- updateSymbolName(projectCols, i, virtualElem, projectedSymbol);
- }
- }
- PlanNode intermediateView = createView(group, virtualElements, unionSource, metadata);
- SymbolMap symbolMap = (SymbolMap)intermediateView.getProperty(Info.SYMBOL_MAP);
- unionSource = intermediateView;
-
- Set<SingleElementSymbol> newGroupingExpressions = Collections.emptySet();
- if (groupingExpressions != null) {
- newGroupingExpressions = new HashSet<SingleElementSymbol>();
- for (SingleElementSymbol singleElementSymbol : groupingExpressions) {
- newGroupingExpressions.add(symbolMap.getKeys().get(virtualElements.indexOf(singleElementSymbol)).clone());
- }
- }
-
- List<SingleElementSymbol> projectedViewSymbols = Util.deepClone(symbolMap.getKeys(), SingleElementSymbol.class);
-
- PlanNode parent = NodeEditor.findParent(unionSource, NodeConstants.Types.SOURCE);
- SymbolMap parentMap = (SymbolMap) parent.getProperty(NodeConstants.Info.SYMBOL_MAP);
- SymbolMap viewMapping = SymbolMap.createSymbolMap(parentMap.getKeys(), projectedViewSymbols);
- for (AggregateSymbol agg : aggregates) {
- agg = (AggregateSymbol)agg.clone();
- ExpressionMappingVisitor.mapExpressions(agg, viewMapping.asMap());
- if (pushdown) {
- projectedViewSymbols.add(agg);
- } else {
- if (agg.getAggregateFunction() == Type.COUNT) {
- if (agg.getExpression() == null) {
- projectedViewSymbols.add(new ExpressionSymbol("stagedAgg", new Constant(1))); //$NON-NLS-1$
- } else {
- SearchedCaseExpression count = new SearchedCaseExpression(Arrays.asList(new IsNullCriteria(agg.getExpression())), Arrays.asList(new Constant(Integer.valueOf(0))));
- count.setElseExpression(new Constant(Integer.valueOf(1)));
- count.setType(DataTypeManager.DefaultDataClasses.INTEGER);
- projectedViewSymbols.add(new ExpressionSymbol("stagedAgg", count)); //$NON-NLS-1$
- }
- } else { //min, max, sum
- Expression ex = agg.getExpression();
- ex = ResolverUtil.convertExpression(ex, DataTypeManager.getDataTypeName(agg.getType()), metadata);
- projectedViewSymbols.add(new ExpressionSymbol("stagedAgg", ex)); //$NON-NLS-1$
- }
- }
- }
-
- if (pushdown) {
- unionSource = addGroupBy(unionSource, newGroupingExpressions, new LinkedList<AggregateSymbol>());
- }
-
- PlanNode projectPlanNode = NodeFactory.getNewNode(NodeConstants.Types.PROJECT);
- unionSource.addAsParent(projectPlanNode);
- unionSource = projectPlanNode;
-
- //create proper names for the aggregate symbols
- Select select = null;
- if (actualProject == null) {
- select = new Select(projectedViewSymbols);
- } else {
- select = new Select(actualProject);
- }
- QueryRewriter.makeSelectUnique(select, false);
- projectedViewSymbols = select.getProjectedSymbols();
- projectPlanNode.setProperty(NodeConstants.Info.PROJECT_COLS, projectedViewSymbols);
- projectPlanNode.addGroup(group);
- if (pushdown) {
- while (RuleRaiseAccess.raiseAccessNode(root, accessNode, metadata, capFinder, true, null) != null) {
- //continue to raise
- }
- }
- }
-
- static PlanNode createView(GroupSymbol group, List<? extends SingleElementSymbol> virtualElements, PlanNode child, QueryMetadataInterface metadata) throws TeiidComponentException {
- SymbolMap symbolMap = createSymbolMap(group, virtualElements, child, metadata);
- return RuleDecomposeJoin.createSource(group, child, symbolMap);
- }
-
- private static SymbolMap createSymbolMap(GroupSymbol group,
+ static SymbolMap createSymbolMap(GroupSymbol group,
List<? extends SingleElementSymbol> virtualElements,
PlanNode child, QueryMetadataInterface metadata)
throws TeiidComponentException, QueryMetadataException {
@@ -585,15 +540,6 @@
return symbolMap;
}
- private void updateSymbolName(List<SingleElementSymbol> projectCols, int i,
- ElementSymbol virtualElem, SingleElementSymbol projectedSymbol) {
- if (projectedSymbol instanceof AliasSymbol) {
- ((AliasSymbol)projectedSymbol).setShortName(virtualElem.getShortCanonicalName());
- } else {
- projectCols.set(i, new AliasSymbol(virtualElem.getShortCanonicalName(), projectedSymbol));
- }
- }
-
/**
* Walk up the plan from the GROUP node. Should encounter only (optionally) a SELECT and can stop at the PROJECT node. Need to
* collect any AggregateSymbols used in the select criteria or projected columns.
@@ -605,23 +551,34 @@
static LinkedHashSet<AggregateSymbol> collectAggregates(PlanNode groupNode) {
LinkedHashSet<AggregateSymbol> aggregates = new LinkedHashSet<AggregateSymbol>();
PlanNode currentNode = groupNode.getParent();
+ SymbolMap symbolMap = (SymbolMap) groupNode.getProperty(NodeConstants.Info.SYMBOL_MAP);
+
while (currentNode != null) {
if (currentNode.getType() == NodeConstants.Types.PROJECT) {
List<SingleElementSymbol> projectedSymbols = (List<SingleElementSymbol>)currentNode.getProperty(NodeConstants.Info.PROJECT_COLS);
for (SingleElementSymbol symbol : projectedSymbols) {
- aggregates.addAll(AggregateSymbolCollectorVisitor.getAggregates(symbol, true));
+ mapAggregates(ElementCollectorVisitor.getAggregates(symbol, true), symbolMap, aggregates);
}
break;
}
if (currentNode.getType() == NodeConstants.Types.SELECT) {
Criteria crit = (Criteria)currentNode.getProperty(NodeConstants.Info.SELECT_CRITERIA);
- aggregates.addAll(AggregateSymbolCollectorVisitor.getAggregates(crit, true));
+ mapAggregates(ElementCollectorVisitor.getAggregates(crit, true), symbolMap, aggregates);
}
currentNode = currentNode.getParent();
}
return aggregates;
}
+
+ static void mapAggregates(Collection<ElementSymbol> symbols, SymbolMap map, Collection<? super AggregateSymbol> aggs) {
+ for (ElementSymbol es : symbols) {
+ Expression ex = map.getMappedExpression(es);
+ if (ex instanceof AggregateSymbol) {
+ aggs.add((AggregateSymbol) ex);
+ }
+ }
+ }
/**
* Attempt to push the group node below one or more joins, manipulating the parent plan as necessary. This may involve
@@ -631,32 +588,39 @@
* @since 4.2
*/
private void pushGroupNode(PlanNode groupNode,
- List<SingleElementSymbol> groupingExpressions,
+ List<Expression> groupingExpressions,
Set<AggregateSymbol> allAggregates,
QueryMetadataInterface metadata,
- CapabilitiesFinder capFinder) throws TeiidComponentException,
+ CapabilitiesFinder capFinder, CommandContext cc) throws TeiidComponentException,
QueryMetadataException, QueryPlannerException {
Map<PlanNode, List<AggregateSymbol>> aggregateMap = createNodeMapping(groupNode, allAggregates, true);
if (aggregateMap == null) {
return;
}
- Map<PlanNode, List<SingleElementSymbol>> groupingMap = createNodeMapping(groupNode, groupingExpressions, false);
+ Map<PlanNode, List<Expression>> groupingMap = createNodeMapping(groupNode, groupingExpressions, false);
Set<PlanNode> possibleTargetNodes = new LinkedHashSet<PlanNode>(aggregateMap.keySet());
possibleTargetNodes.addAll(groupingMap.keySet());
-
+ for (Map.Entry<PlanNode, List<AggregateSymbol>> entry : aggregateMap.entrySet()) {
+ if (AggregateSymbol.areAggregatesCardinalityDependent(entry.getValue())) {
+ //can't change the cardinality on the other side of the join -
+ //unless it's a 1-1 join, in which case this optimization isn't needed
+ //TODO: make a better choice if there are multiple targets
+ possibleTargetNodes.clear();
+ possibleTargetNodes.add(entry.getKey());
+ break;
+ }
+ }
for (PlanNode planNode : possibleTargetNodes) {
- Set<SingleElementSymbol> stagedGroupingSymbols = new LinkedHashSet<SingleElementSymbol>();
- List<AggregateSymbol> aggregates = aggregateMap.get(planNode);
+ Set<Expression> stagedGroupingSymbols = new LinkedHashSet<Expression>();
+ Collection<AggregateSymbol> aggregates = aggregateMap.get(planNode);
if (!canPush(groupNode, stagedGroupingSymbols, planNode)) {
continue;
}
- if (groupingExpressions != null) {
- filterJoinColumns(stagedGroupingSymbols, planNode.getGroups(), groupingExpressions);
- }
+ filterJoinColumns(stagedGroupingSymbols, planNode.getGroups(), groupingExpressions);
collectSymbolsFromOtherAggregates(allAggregates, aggregates, planNode, stagedGroupingSymbols);
@@ -668,7 +632,7 @@
}
if (aggregates != null) {
- stageAggregates(groupNode, metadata, stagedGroupingSymbols, aggregates);
+ aggregates = stageAggregates(groupNode, metadata, stagedGroupingSymbols, aggregates, cc);
} else {
aggregates = new ArrayList<AggregateSymbol>(1);
}
@@ -678,12 +642,15 @@
}
//TODO: if aggregates is empty, then could insert a dup remove node instead
- PlanNode stageGroup = addGroupBy(planNode, stagedGroupingSymbols, aggregates);
-
+ PlanNode stageGroup = addGroupBy(cc, planNode, new ArrayList<Expression>(stagedGroupingSymbols), aggregates, metadata, groupNode.getParent());
+
//check for push down
- if (stageGroup.getFirstChild().getType() == NodeConstants.Types.ACCESS
- && RuleRaiseAccess.canRaiseOverGroupBy(stageGroup, stageGroup.getFirstChild(), aggregates, metadata, capFinder, null)) {
- RuleRaiseAccess.performRaise(null, stageGroup.getFirstChild(), stageGroup);
+ PlanNode accessNode = stageGroup.getFirstChild();
+ if (accessNode.getType() == NodeConstants.Types.ACCESS
+ && RuleRaiseAccess.canRaiseOverGroupBy(stageGroup, accessNode, aggregates, metadata, capFinder, null)) {
+ accessNode.getGroups().clear();
+ accessNode.getGroups().addAll(stageGroup.getGroups());
+ RuleRaiseAccess.performRaise(null, accessNode, stageGroup);
if (stagedGroupingSymbols.isEmpty()) {
RuleRaiseAccess.performRaise(null, stageGroup.getParent(), stageGroup.getParent().getParent());
}
@@ -691,16 +658,14 @@
}
}
- private PlanNode addGroupBy(PlanNode planNode,
- Collection<SingleElementSymbol> stagedGroupingSymbols,
- Collection<AggregateSymbol> aggregates) {
+ private PlanNode addGroupBy(CommandContext cc,
+ PlanNode child, List<Expression> stagedGroupingSymbols,
+ Collection<AggregateSymbol> aggregates, QueryMetadataInterface metadata, PlanNode endNode) throws QueryMetadataException,
+ TeiidComponentException, QueryPlannerException {
PlanNode stageGroup = NodeFactory.getNewNode(NodeConstants.Types.GROUP);
- planNode.addAsParent(stageGroup);
-
- if (!stagedGroupingSymbols.isEmpty()) {
- stageGroup.setProperty(NodeConstants.Info.GROUP_COLS, new ArrayList<SingleElementSymbol>(stagedGroupingSymbols));
- stageGroup.addGroups(GroupsUsedByElementsVisitor.getGroups(stagedGroupingSymbols));
- } else {
+ child.addAsParent(stageGroup);
+ aggregates = new LinkedHashSet<AggregateSymbol>(aggregates);
+ if (stagedGroupingSymbols.isEmpty()) {
// if the source has no rows we need to insert a select node with criteria count(*)>0
PlanNode selectNode = NodeFactory.getNewNode(NodeConstants.Types.SELECT);
AggregateSymbol count = new AggregateSymbol("stagedAgg", NonReserved.COUNT, false, null); //$NON-NLS-1$
@@ -710,48 +675,60 @@
selectNode.setProperty(NodeConstants.Info.IS_HAVING, Boolean.TRUE);
stageGroup.addAsParent(selectNode);
}
+
+ Map<Expression, ElementSymbol> reverseMapping = RelationalPlanner.buildGroupingNode(aggregates, stagedGroupingSymbols, stageGroup, cc, idGenerator).inserseMapping();
+ GroupSymbol newGroup = reverseMapping.values().iterator().next().getGroupSymbol();
+ PlanNode node = stageGroup.getParent();
+ while (node != endNode) {
+ if (node.getType() == NodeConstants.Types.JOIN) {
+ node.getGroups().removeAll(FrameUtil.findJoinSourceNode(stageGroup.getFirstChild()).getGroups());
+ node.getGroups().add(newGroup);
+ }
+ FrameUtil.convertNode(node, null, null, reverseMapping, metadata, false);
+ if (node.getType() == NodeConstants.Types.JOIN) {
+ //reset the left/right/non-equi join criteria
+ RuleChooseJoinStrategy.chooseJoinStrategy(node, metadata);
+ }
+ node = node.getParent();
+ }
return stageGroup;
}
- static void stageAggregates(PlanNode groupNode,
+ Set<AggregateSymbol> stageAggregates(PlanNode groupNode,
QueryMetadataInterface metadata,
- Collection<SingleElementSymbol> stagedGroupingSymbols,
- Collection<AggregateSymbol> aggregates) throws TeiidComponentException, QueryPlannerException {
+ Set<Expression> stagedGroupingSymbols,
+ Collection<AggregateSymbol> aggregates, CommandContext context) throws TeiidComponentException, QueryPlannerException {
//remove any aggregates that are computed over a group by column
- Set<Expression> expressions = new HashSet<Expression>();
- for (SingleElementSymbol expression : stagedGroupingSymbols) {
- expressions.add(SymbolMap.getExpression(expression));
- }
-
for (final Iterator<AggregateSymbol> iterator = aggregates.iterator(); iterator.hasNext();) {
final AggregateSymbol symbol = iterator.next();
Expression expr = symbol.getExpression();
if (expr == null) {
continue;
}
- if (expressions.contains(expr)) {
+ if (stagedGroupingSymbols.contains(expr)) {
iterator.remove();
}
}
- if (!aggregates.isEmpty()) {
- // Fix any aggregate expressions so they correctly recombine the staged aggregates
- try {
- Set<AggregateSymbol> newAggs = new HashSet<AggregateSymbol>();
- Map<AggregateSymbol, Expression> aggMap = buildAggregateMap(aggregates, metadata, newAggs);
- mapExpressions(groupNode.getParent(), aggMap, metadata);
- aggregates.clear();
- aggregates.addAll(newAggs);
- } catch (QueryResolverException err) {
- throw new TeiidComponentException(err);
- }
- }
+ if (aggregates.isEmpty()) {
+ return Collections.emptySet();
+ }
+ // Fix any aggregate expressions so they correctly recombine the staged aggregates
+ Set<AggregateSymbol> newAggs = new HashSet<AggregateSymbol>();
+ Map<AggregateSymbol, Expression> aggMap;
+ try {
+ aggMap = buildAggregateMap(aggregates, metadata, newAggs);
+ } catch (QueryResolverException e) {
+ throw new QueryPlannerException(e, e.getMessage());
+ }
+ updateParentAggs(groupNode, context, aggMap, metadata);
+ return newAggs;
}
private void collectSymbolsFromOtherAggregates(Collection<AggregateSymbol> allAggregates,
Collection<AggregateSymbol> aggregates,
PlanNode current,
- Set<SingleElementSymbol> stagedGroupingSymbols) {
+ Set<Expression> stagedGroupingSymbols) {
Set<AggregateSymbol> otherAggs = new HashSet<AggregateSymbol>(allAggregates);
if (aggregates != null) {
otherAggs.removeAll(aggregates);
@@ -772,7 +749,7 @@
* Ensures that we are only pushing through inner equi joins or cross joins. Also collects the necessary staged grouping symbols
*/
private boolean canPush(PlanNode groupNode,
- Set<SingleElementSymbol> stagedGroupingSymbols,
+ Set<Expression> stagedGroupingSymbols,
PlanNode planNode) {
PlanNode parentJoin = planNode.getParent();
@@ -786,12 +763,12 @@
}
if (planNode == parentJoin.getFirstChild()) {
- if (parentJoin.hasCollectionProperty(NodeConstants.Info.LEFT_EXPRESSIONS) && !filterJoinColumns(stagedGroupingSymbols, groups, (List<SingleElementSymbol>)parentJoin.getProperty(NodeConstants.Info.LEFT_EXPRESSIONS))) {
- return false;
+ if (parentJoin.hasCollectionProperty(NodeConstants.Info.LEFT_EXPRESSIONS)) {
+ filterJoinColumns(stagedGroupingSymbols, groups, (List<SingleElementSymbol>)parentJoin.getProperty(NodeConstants.Info.LEFT_EXPRESSIONS));
}
} else {
- if (parentJoin.hasCollectionProperty(NodeConstants.Info.RIGHT_EXPRESSIONS) && !filterJoinColumns(stagedGroupingSymbols, groups, (List<SingleElementSymbol>)parentJoin.getProperty(NodeConstants.Info.RIGHT_EXPRESSIONS))) {
- return false;
+ if (parentJoin.hasCollectionProperty(NodeConstants.Info.RIGHT_EXPRESSIONS)) {
+ filterJoinColumns(stagedGroupingSymbols, groups, (List<SingleElementSymbol>)parentJoin.getProperty(NodeConstants.Info.RIGHT_EXPRESSIONS));
}
}
@@ -801,21 +778,17 @@
return true;
}
- private boolean filterJoinColumns(Set<SingleElementSymbol> stagedGroupingSymbols,
+ private void filterJoinColumns(Set<Expression> stagedGroupingSymbols,
Set<GroupSymbol> groups,
- List<SingleElementSymbol> symbols) {
- for (SingleElementSymbol singleElementSymbol : symbols) {
- if (!(singleElementSymbol instanceof ElementSymbol)) {
- return false;
+ List<? extends Expression> symbols) {
+ for (Expression ex : symbols) {
+ if (groups.containsAll(GroupsUsedByElementsVisitor.getGroups(ex))) {
+ stagedGroupingSymbols.add(SymbolMap.getExpression(ex));
}
- if (groups.contains(((ElementSymbol)singleElementSymbol).getGroupSymbol())) {
- stagedGroupingSymbols.add(singleElementSymbol);
- }
}
- return true;
}
- private <T extends SingleElementSymbol> Map<PlanNode, List<T>> createNodeMapping(PlanNode groupNode,
+ private <T extends Expression> Map<PlanNode, List<T>> createNodeMapping(PlanNode groupNode,
Collection<T> expressions, boolean aggs) {
Map<PlanNode, List<T>> result = new LinkedHashMap<PlanNode, List<T>>();
if (expressions == null) {
@@ -825,11 +798,14 @@
if (aggs && ((AggregateSymbol)aggregateSymbol).getExpression() == null) {
return null; //count(*) is not yet handled. a general approach would be count(*) => count(r.col) * count(l.col), but the logic here assumes a simpler initial mapping
}
+ if (aggs && !((AggregateSymbol)aggregateSymbol).canStage()) {
+ continue;
+ }
Set<GroupSymbol> groups = GroupsUsedByElementsVisitor.getGroups(aggregateSymbol);
if (groups.isEmpty()) {
continue;
}
- PlanNode originatingNode = FrameUtil.findOriginatingNode(groupNode, groups);
+ PlanNode originatingNode = FrameUtil.findOriginatingNode(groupNode.getFirstChild(), groups);
if (originatingNode == null) {
if (aggs) {
return null; //should never happen
@@ -855,6 +831,10 @@
continue;
}
+ if (originatingNode.getType() != NodeConstants.Types.ACCESS) {
+ continue; //don't perform intermediate grouping
+ }
+
if (aggs && ((AggregateSymbol)aggregateSymbol).isDistinct()) {
//TODO: support distinct
continue;
@@ -873,7 +853,7 @@
private static Map<AggregateSymbol, Expression> buildAggregateMap(Collection<? extends SingleElementSymbol> aggregateExpressions,
QueryMetadataInterface metadata, Set<AggregateSymbol> nestedAggregates) throws QueryResolverException,
TeiidComponentException {
- Map<AggregateSymbol, Expression> aggMap = new HashMap<AggregateSymbol, Expression>();
+ Map<AggregateSymbol, Expression> aggMap = new LinkedHashMap<AggregateSymbol, Expression>();
for (SingleElementSymbol symbol : aggregateExpressions) {
AggregateSymbol partitionAgg = (AggregateSymbol)symbol;
@@ -883,7 +863,6 @@
if (aggFunction == Type.COUNT) {
//COUNT(x) -> CONVERT(SUM(COUNT(x)), INTEGER)
AggregateSymbol newAgg = new AggregateSymbol("stagedAgg", NonReserved.SUM, false, partitionAgg); //$NON-NLS-1$
-
// Build conversion function to convert SUM (which returns LONG) back to INTEGER
Function convertFunc = new Function(FunctionLibrary.CONVERT, new Expression[] {newAgg, new Constant(DataTypeManager.getDataTypeName(partitionAgg.getType()))});
ResolverVisitor.resolveLanguageObject(convertFunc, metadata);
@@ -945,10 +924,7 @@
nestedAggregates.add(countAgg);
nestedAggregates.add(sumAgg);
nestedAggregates.add(sumSqAgg);
- } else if (aggFunction == Type.TEXTAGG) {
- continue;
- }
- else {
+ } else {
//AGG(X) -> AGG(AGG(X))
newExpression = new AggregateSymbol("stagedAgg", aggFunction.name(), false, partitionAgg); //$NON-NLS-1$
nestedAggregates.add(partitionAgg);
@@ -959,22 +935,6 @@
return aggMap;
}
- static void mapExpressions(PlanNode node, Map<? extends Expression, ? extends Expression> exprMap, QueryMetadataInterface metadata)
- throws QueryPlannerException {
-
- while (node != null) {
- FrameUtil.convertNode(node, null, null, exprMap, metadata, true);
-
- switch (node.getType()) {
- case NodeConstants.Types.SOURCE:
- case NodeConstants.Types.GROUP:
- return;
- }
-
- node = node.getParent();
- }
- }
-
/**
* @see java.lang.Object#toString()
* @since 4.2
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-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RulePushSelectCriteria.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -43,6 +43,7 @@
import org.teiid.query.optimizer.relational.plantree.NodeEditor;
import org.teiid.query.optimizer.relational.plantree.NodeFactory;
import org.teiid.query.optimizer.relational.plantree.PlanNode;
+import org.teiid.query.optimizer.relational.plantree.NodeConstants.Info;
import org.teiid.query.resolver.util.AccessPattern;
import org.teiid.query.sql.lang.CompoundCriteria;
import org.teiid.query.sql.lang.Criteria;
@@ -52,7 +53,6 @@
import org.teiid.query.sql.symbol.Expression;
import org.teiid.query.sql.symbol.GroupSymbol;
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;
@@ -113,7 +113,7 @@
boolean moved = false;
- if((critNode.getGroups().isEmpty() && critNode.getSubqueryContainers().isEmpty()) || !atBoundary(critNode, sourceNode)) {
+ if(critNode.hasBooleanProperty(Info.IS_PUSHED) || (critNode.getGroups().isEmpty() && critNode.getSubqueryContainers().isEmpty()) || !atBoundary(critNode, sourceNode)) {
deadNodes.add(critNode);
continue;
}
@@ -132,6 +132,16 @@
break;
}
}
+ case NodeConstants.Types.GROUP:
+ {
+ if (!critNode.hasBooleanProperty(NodeConstants.Info.IS_HAVING)) {
+ SymbolMap symbolMap = (SymbolMap) sourceNode.getProperty(NodeConstants.Info.SYMBOL_MAP);
+ FrameUtil.convertNode(critNode, null, null, symbolMap.asMap(), metadata, true);
+ NodeEditor.removeChildNode(critNode.getParent(), critNode);
+ sourceNode.getFirstChild().addAsParent(critNode);
+ moved = true;
+ }
+ }
}
if (!moved) {
@@ -333,8 +343,6 @@
satisfyAccessPatterns(critNode, currentNode);
} else if (FrameUtil.isOrderedLimit(currentNode)) {
return currentNode;
- } else if (currentNode.getType() == NodeConstants.Types.GROUP && critNode.hasBooleanProperty(NodeConstants.Info.IS_HAVING)) {
- return currentNode;
}
}
@@ -598,7 +606,7 @@
return false;
}
- if (!AggregateSymbolCollectorVisitor.getAggregates(converted, false).isEmpty()) {
+ if (!ElementCollectorVisitor.getAggregates(converted, false).isEmpty()) {
result = Boolean.TRUE;
}
}
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleRaiseAccess.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleRaiseAccess.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleRaiseAccess.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -163,6 +163,8 @@
{
Set<AggregateSymbol> aggregates = RulePushAggregates.collectAggregates(parentNode);
if (canRaiseOverGroupBy(parentNode, accessNode, aggregates, metadata, capFinder, record)) {
+ accessNode.getGroups().clear();
+ accessNode.getGroups().addAll(parentNode.getGroups());
return performRaise(rootNode, accessNode, parentNode);
}
return null;
@@ -302,14 +304,14 @@
if(modelID == null) {
return false;
}
- List<SingleElementSymbol> groupCols = (List<SingleElementSymbol>)groupNode.getProperty(NodeConstants.Info.GROUP_COLS);
+ List<Expression> groupCols = (List<Expression>)groupNode.getProperty(NodeConstants.Info.GROUP_COLS);
if(!CapabilitiesUtil.supportsAggregates(groupCols, modelID, metadata, capFinder)) {
recordDebug("cannot push group by, since group by is not supported by source", groupNode, record); //$NON-NLS-1$
return false;
}
if (groupCols != null) {
- for (SingleElementSymbol singleElementSymbol : groupCols) {
- if (!canPushSymbol(singleElementSymbol, false, modelID, metadata, capFinder, record)) {
+ for (Expression expr : groupCols) {
+ if (!canPushSymbol(expr, false, modelID, metadata, capFinder, record)) {
return false;
}
}
@@ -467,7 +469,7 @@
* @throws QueryMetadataException
* @since 4.1.2
*/
- private static boolean canPushSymbol(SingleElementSymbol symbol, boolean inSelectClause, Object modelID,
+ private static boolean canPushSymbol(Expression symbol, boolean inSelectClause, Object modelID,
QueryMetadataInterface metadata, CapabilitiesFinder capFinder, AnalysisRecord record)
throws TeiidComponentException, QueryMetadataException {
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleRaiseNull.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleRaiseNull.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleRaiseNull.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -44,6 +44,8 @@
import org.teiid.query.sql.lang.OrderByItem;
import org.teiid.query.sql.lang.SetQuery;
import org.teiid.query.sql.symbol.AliasSymbol;
+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.SingleElementSymbol;
@@ -277,7 +279,7 @@
NodeEditor.removeChildNode(joinNode.getParent(), joinNode);
for (GroupSymbol group : nullNode.getGroups()) {
- Map nullSymbolMap = FrameUtil.buildSymbolMap(group, null, metadata);
+ Map<ElementSymbol, Expression> nullSymbolMap = FrameUtil.buildSymbolMap(group, null, metadata);
FrameUtil.convertFrame(frameStart, group, null, nullSymbolMap, metadata);
}
Modified: trunk/engine/src/main/java/org/teiid/query/parser/ParseInfo.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/parser/ParseInfo.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/query/parser/ParseInfo.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -37,9 +37,6 @@
public int referenceCount = 0;
- // This gets set according to the current clause
- public boolean aggregatesAllowed = false;
-
// treat a double quoted variable as variable instead of string
public boolean ansiQuotedIdentifiers=Boolean.valueOf(System.getProperty("org.teiid.ansiQuotedIdentifiers", Boolean.TRUE.toString())).booleanValue(); //$NON-NLS-1$
Modified: trunk/engine/src/main/java/org/teiid/query/processor/relational/DependentCriteriaProcessor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/relational/DependentCriteriaProcessor.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/query/processor/relational/DependentCriteriaProcessor.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -51,6 +51,7 @@
import org.teiid.query.sql.lang.SetCriteria;
import org.teiid.query.sql.symbol.Constant;
import org.teiid.query.sql.symbol.Expression;
+import org.teiid.query.sql.symbol.SingleElementSymbol;
import org.teiid.query.sql.util.ValueIterator;
@@ -90,11 +91,11 @@
DependentValueSource originalVs = (DependentValueSource)dependentNode.getContext().getVariableContext().getGlobalValue(valueSource);
if (!originalVs.isDistinct()) {
if (sortUtility == null) {
- List<Expression> sortSymbols = new ArrayList<Expression>(dependentSetStates.size());
+ List<SingleElementSymbol> sortSymbols = new ArrayList<SingleElementSymbol>(dependentSetStates.size());
List<Boolean> sortDirection = new ArrayList<Boolean>(sortSymbols.size());
for (int i = 0; i < dependentSetStates.size(); i++) {
sortDirection.add(Boolean.valueOf(OrderBy.ASC));
- sortSymbols.add(dependentSetStates.get(i).valueExpression);
+ sortSymbols.add((SingleElementSymbol)dependentSetStates.get(i).valueExpression);
}
this.sortUtility = new SortUtility(originalVs.getTupleBuffer().createIndexedTupleSource(), sortSymbols, sortDirection, Mode.DUP_REMOVE, dependentNode.getBufferManager(), dependentNode.getConnectionID(), originalVs.getTupleBuffer().getSchema());
}
Modified: trunk/engine/src/main/java/org/teiid/query/processor/relational/GroupingNode.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/relational/GroupingNode.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/query/processor/relational/GroupingNode.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -22,8 +22,7 @@
package org.teiid.query.processor.relational;
-import static org.teiid.query.analysis.AnalysisRecord.PROP_GROUP_COLS;
-import static org.teiid.query.analysis.AnalysisRecord.PROP_SORT_MODE;
+import static org.teiid.query.analysis.AnalysisRecord.*;
import java.util.ArrayList;
import java.util.Arrays;
@@ -62,18 +61,19 @@
import org.teiid.query.sql.symbol.AggregateSymbol;
import org.teiid.query.sql.symbol.ElementSymbol;
import org.teiid.query.sql.symbol.Expression;
-import org.teiid.query.sql.symbol.SingleElementSymbol;
import org.teiid.query.sql.symbol.TextLine;
import org.teiid.query.sql.symbol.AggregateSymbol.Type;
+import org.teiid.query.sql.util.SymbolMap;
import org.teiid.query.util.CommandContext;
public class GroupingNode extends RelationalNode {
// Grouping columns set by the planner
- private List sortElements;
- private List sortTypes;
+ private List<Expression> sortElements;
+ private List<Boolean> sortTypes;
private boolean removeDuplicates;
+ private SymbolMap outputMapping;
// Collection phase
private int phase = COLLECTION;
@@ -87,8 +87,10 @@
// Group phase
private AggregateFunction[] functions;
+ private int[] conditions;
private List lastRow;
private List currentGroupTuple;
+ private Evaluator eval;
private static final int COLLECTION = 1;
private static final int SORT = 2;
@@ -127,12 +129,16 @@
* @param groupingElements
* @since 4.2
*/
- public void setGroupingElements(List groupingElements) {
+ public void setGroupingElements(List<Expression> groupingElements) {
this.sortElements = groupingElements;
if(groupingElements != null) {
sortTypes = Collections.nCopies(groupingElements.size(), Boolean.valueOf(OrderBy.ASC));
}
}
+
+ public void setOutputMapping(SymbolMap outputMapping) {
+ this.outputMapping = outputMapping;
+ }
@Override
public void initialize(CommandContext context, BufferManager bufferManager,
@@ -157,13 +163,20 @@
// Construct aggregate function state accumulators
functions = new AggregateFunction[getElements().size()];
+ conditions = new int[getElements().size()];
for(int i=0; i<getElements().size(); i++) {
- SingleElementSymbol symbol = (SingleElementSymbol)getElements().get(i);
+ Expression symbol = (Expression) getElements().get(i);
+ if (this.outputMapping != null) {
+ symbol = outputMapping.getMappedExpression((ElementSymbol)symbol);
+ }
Class<?> outputType = symbol.getType();
Class<?> inputType = symbol.getType();
+ conditions[i] = -1;
if(symbol instanceof AggregateSymbol) {
AggregateSymbol aggSymbol = (AggregateSymbol) symbol;
-
+ if (aggSymbol.getCondition() != null) {
+ conditions[i] = collectExpression(aggSymbol.getCondition());
+ }
if(aggSymbol.getExpression() == null) {
functions[i] = new Count();
} else {
@@ -198,7 +211,6 @@
break;
default:
functions[i] = new StatsFunction(function);
-
}
if(aggSymbol.isDistinct() && !function.equals(NonReserved.MIN) && !function.equals(NonReserved.MAX)) {
@@ -281,8 +293,6 @@
return new BatchCollector.BatchProducerTupleSource(sourceNode) {
- Evaluator eval = new Evaluator(elementMap, getDataManager(), getContext());
-
@Override
protected List updateTuple(List tuple) throws ExpressionEvaluationException, BlockedException, TeiidComponentException {
int columns = collectedExpressions.size();
@@ -300,14 +310,20 @@
}
private void collectionPhase() {
+ eval = new Evaluator(elementMap, getDataManager(), getContext());
if(this.sortElements == null) {
// No need to sort
this.groupTupleSource = getCollectionTupleSource();
this.phase = GROUP;
} else {
- this.sortUtility = new SortUtility(getCollectionTupleSource(), sortElements,
+ //create a temporary positional schema
+ List<ElementSymbol> schema = new ArrayList<ElementSymbol>();
+ for (int i = 0; i < collectedExpressions.size(); i++) {
+ schema.add(new ElementSymbol(String.valueOf(i)));
+ }
+ this.sortUtility = new SortUtility(getCollectionTupleSource(), schema.subList(0, sortElements.size()),
sortTypes, removeDuplicates?Mode.DUP_REMOVE_SORT:Mode.SORT, getBufferManager(),
- getConnectionID(), collectedExpressions);
+ getConnectionID(), schema);
this.phase = SORT;
}
}
@@ -357,7 +373,7 @@
}
if(lastRow != null || sortElements == null) {
// Close last group
- List row = new ArrayList(functions.length);
+ List<Object> row = new ArrayList<Object>(functions.length);
for(int i=0; i<functions.length; i++) {
row.add( functions[i].getResult() );
}
@@ -397,10 +413,13 @@
return true;
}
- private void updateAggregates(List tuple)
+ private void updateAggregates(List<?> tuple)
throws TeiidComponentException, TeiidProcessingException {
for(int i=0; i<functions.length; i++) {
+ if (conditions[i] != -1 && !Boolean.TRUE.equals(tuple.get(conditions[i]))) {
+ continue;
+ }
functions[i].addInput(tuple);
}
}
@@ -415,6 +434,9 @@
protected void getNodeString(StringBuffer str) {
super.getNodeString(str);
str.append(sortElements);
+ if (outputMapping != null) {
+ str.append(outputMapping);
+ }
}
public Object clone(){
@@ -423,6 +445,7 @@
clonedNode.sortElements = sortElements;
clonedNode.sortTypes = sortTypes;
clonedNode.removeDuplicates = removeDuplicates;
+ clonedNode.outputMapping = outputMapping;
return clonedNode;
}
Modified: trunk/engine/src/main/java/org/teiid/query/processor/relational/SortUtility.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/relational/SortUtility.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/query/processor/relational/SortUtility.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -45,6 +45,7 @@
import org.teiid.query.sql.lang.OrderBy;
import org.teiid.query.sql.lang.OrderByItem;
import org.teiid.query.sql.symbol.Expression;
+import org.teiid.query.sql.symbol.SingleElementSymbol;
/**
@@ -152,7 +153,7 @@
this.comparator.setNullOrdering(nullOrderings);
}
- public SortUtility(TupleSource ts, List expressions, List<Boolean> types,
+ public SortUtility(TupleSource ts, List<? extends SingleElementSymbol> expressions, List<Boolean> types,
Mode mode, BufferManager bufferManager, String connectionID, List schema) {
this(ts, new OrderBy(expressions, types).getOrderByItems(), mode, bufferManager, connectionID, schema);
}
Modified: trunk/engine/src/main/java/org/teiid/query/resolver/util/ResolverUtil.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/resolver/util/ResolverUtil.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/query/resolver/util/ResolverUtil.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -333,7 +333,7 @@
List<SingleElementSymbol> knownElements = command.getProjectedQuery().getSelect().getProjectedSymbols();
boolean isSimpleQuery = false;
- List fromClauseGroups = Collections.emptyList();
+ List<GroupSymbol> fromClauseGroups = Collections.emptyList();
if (command instanceof Query) {
Query query = (Query)command;
Modified: trunk/engine/src/main/java/org/teiid/query/resolver/util/ResolverVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/resolver/util/ResolverVisitor.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/query/resolver/util/ResolverVisitor.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -57,6 +57,7 @@
import org.teiid.query.sql.lang.SubqueryCompareCriteria;
import org.teiid.query.sql.lang.SubquerySetCriteria;
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.DerivedColumn;
@@ -423,6 +424,17 @@
handleException(e);
}
}
+
+ @Override
+ public void visit(AggregateSymbol obj) {
+ if (obj.getCondition() != null) {
+ try {
+ obj.setCondition(ResolverUtil.convertExpression(obj.getCondition(), DataTypeManager.DefaultDataTypes.BOOLEAN, metadata));
+ } catch (QueryResolverException e) {
+ handleException(e);
+ }
+ }
+ }
public TeiidComponentException getComponentException() {
return this.componentException;
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-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -148,6 +148,7 @@
import org.teiid.query.sql.symbol.Reference;
import org.teiid.query.sql.symbol.ScalarSubquery;
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.AggregateSymbol.Type;
import org.teiid.query.sql.util.SymbolMap;
@@ -759,83 +760,17 @@
* Converts a group by with expressions into a group by with only element symbols and an inline view
* @param query
* @return
- * @throws QueryValidatorException
+ * @throws TeiidProcessingException
+ * @throws TeiidComponentException
*/
- private Query rewriteGroupBy(Query query) throws TeiidComponentException, TeiidProcessingException{
+ private Query rewriteGroupBy(Query query) throws TeiidComponentException, TeiidProcessingException {
if (query.getGroupBy() == null) {
return query;
}
if (isDistinctWithGroupBy(query)) {
query.getSelect().setDistinct(false);
}
- // we check for group by expressions here to create an ANSI SQL plan
- boolean hasExpression = false;
- for (final Iterator iterator = query.getGroupBy().getSymbols().iterator(); !hasExpression && iterator.hasNext();) {
- hasExpression = iterator.next() instanceof ExpressionSymbol;
- }
- if (!hasExpression) {
- return query;
- }
- Select select = query.getSelect();
- GroupBy groupBy = query.getGroupBy();
- query.setGroupBy(null);
- Criteria having = query.getHaving();
- query.setHaving(null);
- OrderBy orderBy = query.getOrderBy();
- query.setOrderBy(null);
- Limit limit = query.getLimit();
- query.setLimit(null);
- Into into = query.getInto();
- query.setInto(null);
- Set<Expression> newSelectColumns = new HashSet<Expression>();
- for (final Iterator iterator = groupBy.getSymbols().iterator(); iterator.hasNext();) {
- newSelectColumns.add(SymbolMap.getExpression((SingleElementSymbol)iterator.next()));
- }
- Set<AggregateSymbol> aggs = new HashSet<AggregateSymbol>();
- aggs.addAll(AggregateSymbolCollectorVisitor.getAggregates(select, true));
- if (having != null) {
- aggs.addAll(AggregateSymbolCollectorVisitor.getAggregates(having, true));
- }
- for (AggregateSymbol aggregateSymbol : aggs) {
- if (aggregateSymbol.getExpression() != null) {
- Expression expr = aggregateSymbol.getExpression();
- newSelectColumns.add(SymbolMap.getExpression(expr));
- }
- }
- Select innerSelect = new Select();
- int index = 0;
- for (Expression expr : newSelectColumns) {
- if (expr instanceof SingleElementSymbol) {
- innerSelect.addSymbol((SingleElementSymbol)expr);
- } else {
- innerSelect.addSymbol(new ExpressionSymbol("EXPR" + index++ , expr)); //$NON-NLS-1$
- }
- }
- query.setSelect(innerSelect);
- Query outerQuery = null;
- try {
- outerQuery = QueryRewriter.createInlineViewQuery(new GroupSymbol("X"), query, metadata, query.getSelect().getProjectedSymbols()); //$NON-NLS-1$
- } catch (TeiidException err) {
- throw new TeiidRuntimeException(err);
- }
- Iterator<SingleElementSymbol> iter = outerQuery.getSelect().getProjectedSymbols().iterator();
- HashMap<Expression, SingleElementSymbol> expressionMap = new HashMap<Expression, SingleElementSymbol>();
- for (SingleElementSymbol symbol : query.getSelect().getProjectedSymbols()) {
- expressionMap.put(SymbolMap.getExpression(symbol), iter.next());
- }
- ExpressionMappingVisitor.mapExpressions(groupBy, expressionMap);
- outerQuery.setGroupBy(groupBy);
- ExpressionMappingVisitor.mapExpressions(having, expressionMap);
- outerQuery.setHaving(having);
- ExpressionMappingVisitor.mapExpressions(orderBy, expressionMap);
- outerQuery.setOrderBy(orderBy);
- outerQuery.setLimit(limit);
- ExpressionMappingVisitor.mapExpressions(select, expressionMap);
- outerQuery.setSelect(select);
- outerQuery.setInto(into);
- outerQuery.setOption(query.getOption());
- query = outerQuery;
- rewriteExpressions(innerSelect);
+ rewriteExpressions(query.getGroupBy());
return query;
}
@@ -848,7 +783,7 @@
for (SingleElementSymbol selectExpr : query.getSelect().getProjectedSymbols()) {
selectExpressions.add(SymbolMap.getExpression(selectExpr));
}
- for (SingleElementSymbol groupByExpr : (List<SingleElementSymbol>)groupBy.getSymbols()) {
+ for (Expression groupByExpr : groupBy.getSymbols()) {
if (!selectExpressions.contains(groupByExpr)) {
return false;
}
@@ -2311,6 +2246,17 @@
expression.setAggregateFunction(Type.MAX);
}
}
+ if (expression.getExpression() != null && expression.getCondition() != null && !expression.respectsNulls()) {
+ Expression cond = expression.getCondition();
+ Expression ex = expression.getExpression();
+ if (!(cond instanceof Criteria)) {
+ cond = new ExpressionCriteria(cond);
+ }
+ SearchedCaseExpression sce = new SearchedCaseExpression(Arrays.asList(cond), Arrays.asList(ex));
+ sce.setType(ex.getType());
+ expression.setCondition(null);
+ expression.setExpression(sce);
+ }
return expression;
}
@@ -2756,7 +2702,7 @@
select.setSymbols(select.getProjectedSymbols());
- List symbols = select.getSymbols();
+ List<SelectSymbol> symbols = select.getSymbols();
HashSet<String> uniqueNames = new HashSet<String>();
Modified: trunk/engine/src/main/java/org/teiid/query/sql/LanguageVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/LanguageVisitor.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/query/sql/LanguageVisitor.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -97,6 +97,7 @@
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;
@@ -223,4 +224,6 @@
public void visit(AlterView obj) {}
public void visit(AlterProcedure obj) {}
public void visit(AlterTrigger obj) {}
+
+ public void visit(WindowFunction windowFunction) {}
}
Modified: trunk/engine/src/main/java/org/teiid/query/sql/lang/GroupBy.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/lang/GroupBy.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/query/sql/lang/GroupBy.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -23,13 +23,10 @@
package org.teiid.query.sql.lang;
import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
import java.util.List;
import org.teiid.core.util.EquivalenceUtil;
import org.teiid.core.util.HashCodeUtil;
-import org.teiid.query.QueryPlugin;
import org.teiid.query.sql.LanguageObject;
import org.teiid.query.sql.LanguageVisitor;
import org.teiid.query.sql.symbol.Expression;
@@ -46,7 +43,7 @@
public class GroupBy implements LanguageObject {
/** The set of expressions for the data elements to be group. */
- private List symbols; // List<Expression>
+ private List<Expression> symbols;
// =========================================================================
// C O N S T R U C T O R S
@@ -56,15 +53,15 @@
* Constructs a default instance of this class.
*/
public GroupBy() {
- symbols = new ArrayList();
+ symbols = new ArrayList<Expression>();
}
/**
* Constructs an instance of this class from an ordered set of symbols.
* @param symbols The ordered list of {@link org.teiid.query.sql.symbol.ElementSymbol}s
*/
- public GroupBy( List symbols ) {
- this.symbols = new ArrayList( symbols );
+ public GroupBy( List<? extends Expression> symbols ) {
+ this.symbols = new ArrayList<Expression>( symbols );
}
// =========================================================================
@@ -83,7 +80,7 @@
* Returns an ordered list of the symbols in the GROUP BY
* @return List of {@link org.teiid.query.sql.symbol.ElementSymbol}s
*/
- public List getSymbols() {
+ public List<Expression> getSymbols() {
return symbols;
}
@@ -97,19 +94,6 @@
}
}
- /**
- * Replaces the existing set of symbols with a new collection of symbols
- * @param symbols Collection of {@link org.teiid.query.sql.symbol.ElementSymbol}s
- * to replace current symbols with
- */
- public void replaceSymbols( Collection symbols ) {
- if(symbols == null) {
- throw new IllegalArgumentException(QueryPlugin.Util.getString("ERR.015.010.0003")); //$NON-NLS-1$
- }
-
- this.symbols = new ArrayList(symbols);
- }
-
public void acceptVisitor(LanguageVisitor visitor) {
visitor.visit(this);
}
@@ -123,15 +107,7 @@
* @return Deep copy of object
*/
public Object clone() {
- List thisSymbols = getSymbols();
- List copySymbols = new ArrayList(thisSymbols.size());
- Iterator iter = thisSymbols.iterator();
- while(iter.hasNext()) {
- Expression es = (Expression) iter.next();
- copySymbols.add(es.clone());
- }
-
- return new GroupBy(copySymbols);
+ return new GroupBy(LanguageObject.Util.deepClone(this.symbols, Expression.class));
}
/**
Modified: trunk/engine/src/main/java/org/teiid/query/sql/navigator/PreOrPostOrderNavigator.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/navigator/PreOrPostOrderNavigator.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/query/sql/navigator/PreOrPostOrderNavigator.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -102,6 +102,7 @@
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;
@@ -140,12 +141,12 @@
visitVisitor(obj);
}
}
-
public void visit(AggregateSymbol obj) {
preVisitVisitor(obj);
visitNode(obj.getExpression());
visitNode(obj.getOrderBy());
+ visitNode(obj.getCondition());
postVisitVisitor(obj);
}
public void visit(AliasSymbol obj) {
@@ -700,6 +701,15 @@
postVisitVisitor(obj);
}
+ @Override
+ public void visit(WindowFunction obj) {
+ preVisitVisitor(obj);
+ visitNode(obj.getFunction());
+ visitNodes(obj.getPartition());
+ visitNode(obj.getOrderBy());
+ postVisitVisitor(obj);
+ }
+
public static void doVisit(LanguageObject object, LanguageVisitor visitor, boolean order) {
doVisit(object, visitor, order, false);
}
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-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/query/sql/symbol/AggregateSymbol.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -34,14 +34,7 @@
/**
- * <p>An aggregate symbol represents an aggregate function in the SELECT or HAVING clauses. It
- * extends ExpressionSymbol as they have many things in common. The aggregate symbol is
- * typically something like <code>SUM(stock.quantity * 2)</code>. There are five supported
- * aggregate functions: COUNT, SUM, AVG, MIN, and MAX. Aggregate functions contain an expression -
- * this data is managed by the super class, ExpressionSymbol. Aggregate functions may also
- * specify a DISTINCT flag to indicate that duplicates should be ignored. The DISTINCT flag
- * may be set for all five aggregate functions but is ignored for the computation of MIN and MAX.
- * One special use of an aggregate symbol is for the symbol <code>COUNT(*)</code>. The * expression
+ * <p>An aggregate symbol represents an aggregate function. The * expression
* is encoded by setting the expression to null. This may ONLY be used with the COUNT function.</p>
*
* <p>The type of an aggregate symbol depends on the function and the type of the underlying
@@ -69,12 +62,16 @@
STDDEV_POP,
STDDEV_SAMP,
VAR_POP,
- VAR_SAMP;
+ VAR_SAMP,
+ RANK,
+ DENSE_RANK,
+ ROW_NUMBER;
}
private Type aggregate;
private boolean distinct;
private OrderBy orderBy;
+ private Expression condition;
private static final Class<Integer> COUNT_TYPE = DataTypeManager.DefaultDataClasses.INTEGER;
private static final Map<Class<?>, Class<?>> SUM_TYPES;
@@ -179,6 +176,8 @@
return DataTypeManager.DefaultDataClasses.DOUBLE;
} else if (this.aggregate == Type.ARRAY_AGG) {
return DataTypeManager.DefaultDataClasses.OBJECT;
+ } else if (this.aggregate == Type.RANK || this.aggregate == Type.ROW_NUMBER || this.aggregate == Type.DENSE_RANK){
+ return DataTypeManager.DefaultDataClasses.INTEGER;
} else {
return this.getExpression().getType();
}
@@ -222,6 +221,9 @@
if (orderBy != null) {
copy.setOrderBy(orderBy.clone());
}
+ if (condition != null) {
+ copy.setCondition((Expression) condition.clone());
+ }
return copy;
}
@@ -246,6 +248,7 @@
return this.aggregate.equals(other.aggregate)
&& this.distinct == other.distinct
&& EquivalenceUtil.areEqual(this.getExpression(), other.getExpression())
+ && EquivalenceUtil.areEqual(this.condition, other.condition)
&& EquivalenceUtil.areEqual(this.getOrderBy(), other.getOrderBy());
}
@@ -261,10 +264,19 @@
case VAR_POP:
case VAR_SAMP:
case SUM:
+ case ARRAY_AGG:
return true;
}
return false;
}
+
+ public Expression getCondition() {
+ return condition;
+ }
+
+ public void setCondition(Expression condition) {
+ this.condition = condition;
+ }
public static boolean areAggregatesCardinalityDependent(Collection<AggregateSymbol> aggs) {
for (AggregateSymbol aggregateSymbol : aggs) {
@@ -274,5 +286,21 @@
}
return false;
}
+
+ public boolean respectsNulls() {
+ return this.aggregate == Type.ARRAY_AGG;
+ }
+
+ public boolean canStage() {
+ switch (this.aggregate) {
+ case TEXTAGG:
+ return false;
+ case ARRAY_AGG:
+ return false;
+ case XMLAGG:
+ return orderBy == null;
+ }
+ return true;
+ }
}
Modified: trunk/engine/src/main/java/org/teiid/query/sql/symbol/AliasSymbol.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/symbol/AliasSymbol.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/query/sql/symbol/AliasSymbol.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -82,7 +82,7 @@
* Get the type of the symbol
* @return Type of the symbol
*/
- public Class getType() {
+ public Class<?> getType() {
return this.symbol.getType();
}
Modified: trunk/engine/src/main/java/org/teiid/query/sql/symbol/ElementSymbol.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/symbol/ElementSymbol.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/query/sql/symbol/ElementSymbol.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -46,7 +46,8 @@
private GroupSymbol groupSymbol;
private Object metadataID;
private Class<?> type;
- private boolean isExternalReference = false;
+ private boolean isExternalReference;
+ private boolean isAggregate;
private DisplayMode displayMode = DisplayMode.OUTPUT_NAME;
@@ -262,7 +263,16 @@
copy.setIsExternalReference(isExternalReference());
copy.outputName = this.outputName;
copy.setDisplayMode(this.getDisplayMode());
+ copy.isAggregate = isAggregate;
return copy;
}
+ public boolean isAggregate() {
+ return isAggregate;
+ }
+
+ public void setAggregate(boolean isAggregate) {
+ this.isAggregate = isAggregate;
+ }
+
}
Modified: trunk/engine/src/main/java/org/teiid/query/sql/symbol/ExpressionSymbol.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/symbol/ExpressionSymbol.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/query/sql/symbol/ExpressionSymbol.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -34,7 +34,6 @@
*/
public class ExpressionSymbol extends SingleElementSymbol {
private Expression expression;
- private boolean derivedExpression;
/**
* Constructor used for cloning
@@ -101,19 +100,9 @@
clonedExpr = (Expression) getExpression().clone();
}
ExpressionSymbol copy = new ExpressionSymbol(getName(), getCanonical(), clonedExpr);
- copy.setDerivedExpression(this.derivedExpression);
return copy;
}
- public boolean isDerivedExpression() {
- return this.derivedExpression;
- }
-
- public void setDerivedExpression(boolean derivedExpression) {
- this.derivedExpression = derivedExpression;
- }
-
-
/**
* @see org.teiid.query.sql.symbol.Symbol#hashCode()
*/
Added: trunk/engine/src/main/java/org/teiid/query/sql/symbol/WindowFunction.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/symbol/WindowFunction.java (rev 0)
+++ trunk/engine/src/main/java/org/teiid/query/sql/symbol/WindowFunction.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -0,0 +1,114 @@
+/*
+ * 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.sql.symbol;
+
+import java.util.List;
+
+import org.teiid.core.util.EquivalenceUtil;
+import org.teiid.core.util.HashCodeUtil;
+import org.teiid.query.sql.LanguageObject;
+import org.teiid.query.sql.LanguageVisitor;
+import org.teiid.query.sql.lang.OrderBy;
+
+public class WindowFunction implements Expression {
+
+ private AggregateSymbol function;
+ private List<Expression> partition;
+ private OrderBy orderBy;
+
+ public WindowFunction() {
+
+ }
+
+ public AggregateSymbol getFunction() {
+ return function;
+ }
+
+ public void setFunction(AggregateSymbol 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 boolean isResolved() {
+ return function.isResolved();
+ }
+
+ @Override
+ public void acceptVisitor(LanguageVisitor visitor) {
+ visitor.visit(this);
+ }
+
+ @Override
+ public int hashCode() {
+ return HashCodeUtil.hashCode(function.hashCode(), partition, orderBy);
+ }
+
+ @Override
+ 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);
+ }
+
+ @Override
+ public WindowFunction clone() {
+ WindowFunction clone = new WindowFunction();
+ clone.setFunction((AggregateSymbol) this.function.clone());
+ if (this.partition != null) {
+ clone.setPartition(LanguageObject.Util.deepClone(this.partition, Expression.class));
+ }
+ if (this.orderBy != null) {
+ clone.setOrderBy(this.orderBy.clone());
+ }
+ return clone;
+ }
+
+}
Property changes on: trunk/engine/src/main/java/org/teiid/query/sql/symbol/WindowFunction.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
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-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/query/sql/visitor/AggregateSymbolCollectorVisitor.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -32,7 +32,6 @@
import org.teiid.query.sql.navigator.PreOrPostOrderNavigator;
import org.teiid.query.sql.symbol.AggregateSymbol;
import org.teiid.query.sql.symbol.ElementSymbol;
-import org.teiid.query.sql.symbol.ExpressionSymbol;
import org.teiid.query.sql.symbol.SingleElementSymbol;
@@ -50,25 +49,12 @@
postVisitVisitor(obj);
}
- /**
- * @see org.teiid.query.sql.navigator.PreOrPostOrderNavigator#visit(org.teiid.query.sql.symbol.ExpressionSymbol)
- */
- @Override
- public void visit(ExpressionSymbol obj) {
- if (obj.isDerivedExpression()) {
- preVisitVisitor(obj);
- postVisitVisitor(obj);
- } else {
- super.visit(obj);
- }
- }
-
}
- private Collection<AggregateSymbol> aggregates;
- private Collection<SingleElementSymbol> groupingSymbols;
+ private Collection<? super AggregateSymbol> aggregates;
+ private Collection<? super SingleElementSymbol> groupingSymbols;
- public AggregateSymbolCollectorVisitor(Collection<AggregateSymbol> aggregates, Collection<SingleElementSymbol> elements) {
+ public AggregateSymbolCollectorVisitor(Collection<? super AggregateSymbol> aggregates, Collection<? super SingleElementSymbol> elements) {
this.aggregates = aggregates;
this.groupingSymbols = elements;
}
@@ -79,23 +65,16 @@
}
}
- public void visit(ExpressionSymbol obj) {
- if (this.groupingSymbols != null && obj.isDerivedExpression()) {
- this.groupingSymbols.add(obj);
- }
- }
-
public void visit(ElementSymbol obj) {
if (this.groupingSymbols != null) {
this.groupingSymbols.add(obj);
}
}
- public static final void getAggregates(LanguageObject obj, Collection<SingleElementSymbol> aggregates, Collection<SingleElementSymbol> elements) {
- AggregateSymbolCollectorVisitor visitor = new AggregateSymbolCollectorVisitor(new ArrayList<AggregateSymbol>(), elements);
+ public static final void getAggregates(LanguageObject obj, Collection<? super AggregateSymbol> aggregates, Collection<SingleElementSymbol> elements) {
+ AggregateSymbolCollectorVisitor visitor = new AggregateSymbolCollectorVisitor(aggregates, elements);
AggregateStopNavigator asn = new AggregateStopNavigator(visitor);
obj.acceptVisitor(asn);
- aggregates.addAll(visitor.aggregates);
}
public static final Collection<AggregateSymbol> getAggregates(LanguageObject obj, boolean removeDuplicates) {
Modified: trunk/engine/src/main/java/org/teiid/query/sql/visitor/ElementCollectorVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/visitor/ElementCollectorVisitor.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/query/sql/visitor/ElementCollectorVisitor.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -49,7 +49,8 @@
*/
public class ElementCollectorVisitor extends LanguageVisitor {
- private Collection<ElementSymbol> elements;
+ private Collection<? super ElementSymbol> elements;
+ private boolean aggsOnly;
/**
* Construct a new visitor with the specified collection, which should
@@ -57,7 +58,7 @@
* @param elements Collection to use for elements
* @throws IllegalArgumentException If elements is null
*/
- public ElementCollectorVisitor(Collection<ElementSymbol> elements) {
+ public ElementCollectorVisitor(Collection<? super ElementSymbol> elements) {
if(elements == null) {
throw new IllegalArgumentException(QueryPlugin.Util.getString("ERR.015.010.0021")); //$NON-NLS-1$
}
@@ -65,21 +66,14 @@
}
/**
- * Get the elements collected by the visitor. This should best be called
- * after the visitor has been run on the language object tree.
- * @return Collection of {@link org.teiid.query.sql.symbol.ElementSymbol}
- */
- public Collection<ElementSymbol> getElements() {
- return this.elements;
- }
-
- /**
* Visit a language object and collect symbols. This method should <b>NOT</b> be
* called directly.
* @param obj Language object
*/
public void visit(ElementSymbol obj) {
- this.elements.add(obj);
+ if (!aggsOnly || obj.isAggregate()) {
+ this.elements.add(obj);
+ }
}
/**
@@ -109,7 +103,7 @@
* @param obj Language object
* @param elements Collection to collect elements in
*/
- public static final void getElements(LanguageObject obj, Collection<ElementSymbol> elements) {
+ public static final void getElements(LanguageObject obj, Collection<? super ElementSymbol> elements) {
if(obj == null) {
return;
}
@@ -150,6 +144,10 @@
* @return Collection of {@link org.teiid.query.sql.symbol.ElementSymbol}
*/
public static final Collection<ElementSymbol> getElements(LanguageObject obj, boolean removeDuplicates, boolean useDeepIteration) {
+ return getElements(obj, removeDuplicates, useDeepIteration, false);
+ }
+
+ public static final Collection<ElementSymbol> getElements(LanguageObject obj, boolean removeDuplicates, boolean useDeepIteration, boolean aggsOnly) {
if(obj == null) {
return Collections.emptyList();
}
@@ -159,16 +157,20 @@
} else {
elements = new ArrayList<ElementSymbol>();
}
- ElementCollectorVisitor visitor = null;
+ ElementCollectorVisitor visitor = new ElementCollectorVisitor(elements);
+ visitor.aggsOnly = aggsOnly;
if (useDeepIteration){
- visitor = new ElementCollectorVisitor(elements);
DeepPreOrderNavigator.doVisit(obj, visitor);
} else {
- visitor = new ElementCollectorVisitor(elements);
PreOrderNavigator.doVisit(obj, visitor);
}
return elements;
}
+
+ public static final Collection<ElementSymbol> getAggregates(LanguageObject obj, boolean removeDuplicates) {
+ return getElements(obj, removeDuplicates, false, true);
+ }
+
}
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-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/query/sql/visitor/ExpressionMappingVisitor.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -24,6 +24,7 @@
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
@@ -52,6 +53,7 @@
import org.teiid.query.sql.lang.SubquerySetCriteria;
import org.teiid.query.sql.lang.XMLTable;
import org.teiid.query.sql.lang.XMLTable.XMLColumn;
+import org.teiid.query.sql.navigator.PreOrPostOrderNavigator;
import org.teiid.query.sql.navigator.PreOrderNavigator;
import org.teiid.query.sql.proc.AssignmentStatement;
import org.teiid.query.sql.symbol.AggregateSymbol;
@@ -78,6 +80,7 @@
private Map symbolMap;
private boolean clone = true;
+ private boolean elementSymbolsOnly;
/**
* Constructor for ExpressionMappingVisitor.
@@ -251,7 +254,7 @@
public void visit(SearchedCaseExpression obj) {
int whenCount = obj.getWhenCount();
- ArrayList thens = new ArrayList(whenCount);
+ ArrayList<Expression> thens = new ArrayList<Expression>(whenCount);
for (int i = 0; i < whenCount; i++) {
thens.add(replaceExpression(obj.getThenExpression(i)));
}
@@ -299,6 +302,9 @@
}
public Expression replaceExpression(Expression element) {
+ if (elementSymbolsOnly && !(element instanceof ElementSymbol)) {
+ return element;
+ }
Expression mapped = (Expression) this.symbolMap.get(element);
if(mapped != null) {
if (clone) {
@@ -310,17 +316,20 @@
}
public void visit(StoredProcedure obj) {
- for (Iterator paramIter = obj.getInputParameters().iterator(); paramIter.hasNext();) {
- SPParameter param = (SPParameter) paramIter.next();
+ for (Iterator<SPParameter> paramIter = obj.getInputParameters().iterator(); paramIter.hasNext();) {
+ SPParameter param = paramIter.next();
Expression expr = param.getExpression();
param.setExpression(replaceExpression(expr));
}
}
public void visit(AggregateSymbol obj) {
- if (obj.getExpression() != null) { //account for count(*) - TODO: clean this up
+ if (obj.getExpression() != null) {
obj.setExpression(replaceExpression(obj.getExpression()));
}
+ if (obj.getCondition() != null) {
+ obj.setCondition(replaceExpression(obj.getCondition()));
+ }
}
/**
@@ -328,7 +337,11 @@
* @param obj Object to remap
*/
public void visit(GroupBy obj) {
- replaceSymbols(obj.getSymbols(), false);
+ List<Expression> symbols = obj.getSymbols();
+ for (int i = 0; i < symbols.size(); i++) {
+ Expression symbol = symbols.get(i);
+ symbols.set(i, replaceExpression(symbol));
+ }
}
@Override
@@ -371,21 +384,35 @@
* @param obj Language object
* @param exprMap Expression map, Expression to Expression
*/
- public static void mapExpressions(LanguageObject obj, Map exprMap) {
+ public static void mapExpressions(LanguageObject obj, Map<? extends Expression, ? extends Expression> exprMap) {
if(obj == null || exprMap == null || exprMap.isEmpty()) {
return;
}
- final Set reverseSet = new HashSet(exprMap.values());
final ExpressionMappingVisitor visitor = new ExpressionMappingVisitor(exprMap);
- PreOrderNavigator pon = new PreOrderNavigator(visitor) {
- @Override
- protected void visitNode(LanguageObject obj) {
- if (!(obj instanceof Expression) || !reverseSet.contains(obj)) {
- super.visitNode(obj);
- }
+ visitor.elementSymbolsOnly = true;
+ for (Map.Entry<? extends Expression, ? extends Expression> entry : exprMap.entrySet()) {
+ if (!(entry.getKey() instanceof ElementSymbol)) {
+ visitor.elementSymbolsOnly = false;
+ break;
}
- };
- obj.acceptVisitor(pon);
+ }
+ boolean useReverseMapping = !Collections.disjoint(GroupsUsedByElementsVisitor.getGroups(exprMap.keySet()),
+ GroupsUsedByElementsVisitor.getGroups(exprMap.values()));
+
+ if (useReverseMapping) {
+ final Set<Expression> reverseSet = new HashSet<Expression>(exprMap.values());
+ PreOrderNavigator pon = new PreOrderNavigator(visitor) {
+ @Override
+ protected void visitNode(LanguageObject obj) {
+ if (!(obj instanceof Expression) || !reverseSet.contains(obj)) {
+ super.visitNode(obj);
+ }
+ }
+ };
+ obj.acceptVisitor(pon);
+ } else {
+ PreOrPostOrderNavigator.doVisit(obj, visitor, PreOrPostOrderNavigator.PRE_ORDER, false);
+ }
}
protected void setVariableValues(Map variableValues) {
Modified: trunk/engine/src/main/java/org/teiid/query/sql/visitor/GroupsUsedByElementsVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/visitor/GroupsUsedByElementsVisitor.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/query/sql/visitor/GroupsUsedByElementsVisitor.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -42,7 +42,9 @@
Collection<ElementSymbol> elements = ElementCollectorVisitor.getElements(obj, true);
for (ElementSymbol elementSymbol : elements) {
- groups.add(elementSymbol.getGroupSymbol());
+ if (elementSymbol.getGroupSymbol() != null) {
+ groups.add(elementSymbol.getGroupSymbol());
+ }
}
}
Modified: trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -126,6 +126,7 @@
import org.teiid.query.sql.symbol.SelectSymbol;
import org.teiid.query.sql.symbol.SingleElementSymbol;
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;
@@ -133,6 +134,7 @@
import org.teiid.query.sql.symbol.XMLParse;
import org.teiid.query.sql.symbol.XMLQuery;
import org.teiid.query.sql.symbol.XMLSerialize;
+import org.teiid.query.sql.symbol.AggregateSymbol.Type;
import org.teiid.query.sql.symbol.XMLNamespaces.NamespaceItem;
import org.teiid.translator.SourceSystemFunctions;
@@ -1123,7 +1125,9 @@
}
if (obj.getExpression() == null) {
- append(Tokens.ALL_COLS);
+ if (obj.getAggregateFunction() == Type.COUNT) {
+ append(Tokens.ALL_COLS);
+ }
} else {
visitNode(obj.getExpression());
}
@@ -1133,6 +1137,16 @@
visitNode(obj.getOrderBy());
}
append(")"); //$NON-NLS-1$
+
+ if (obj.getCondition() != null) {
+ append(SPACE);
+ append(FILTER);
+ append(Tokens.LPAREN);
+ append(WHERE);
+ append(SPACE);
+ append(obj.getCondition());
+ append(Tokens.RPAREN);
+ }
}
public void visit( AliasSymbol obj ) {
@@ -2034,6 +2048,31 @@
addTabs(0);
append(alterView.getDefinition());
}
+
+ @Override
+ public void visit(WindowFunction windowFunction) {
+ append(windowFunction.getFunction());
+ append(SPACE);
+ append(OVER);
+ append(SPACE);
+ append(Tokens.LPAREN);
+ boolean needsSpace = false;
+ if (windowFunction.getPartition() != null) {
+ append(PARTITION);
+ append(SPACE);
+ append(BY);
+ append(SPACE);
+ registerNodes(windowFunction.getPartition(), 0);
+ needsSpace = true;
+ }
+ if (windowFunction.getOrderBy() != null) {
+ if (needsSpace) {
+ append(SPACE);
+ }
+ append(windowFunction.getOrderBy());
+ }
+ append(Tokens.RPAREN);
+ }
public static String escapeSinglePart( String part ) {
if (isReservedWord(part)) {
Modified: trunk/engine/src/main/java/org/teiid/query/util/CommandContext.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/util/CommandContext.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/query/util/CommandContext.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -434,13 +434,12 @@
}
public Set<String> getGroups() {
+ if (globalState.groups == null) {
+ globalState.groups = new HashSet<String>();
+ }
return globalState.groups;
}
- public void setGroups(Set<String> groups) {
- this.globalState.groups = groups;
- }
-
public long getTimeSliceEnd() {
return globalState.timeSliceEnd;
}
Modified: trunk/engine/src/main/java/org/teiid/query/validator/AggregateValidationVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/validator/AggregateValidationVisitor.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/query/validator/AggregateValidationVisitor.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -59,13 +59,9 @@
public void visit(AggregateSymbol obj) {
Expression aggExp = obj.getExpression();
- // Check for any nested aggregates (which are not allowed)
- if(aggExp != null) {
- Collection<AggregateSymbol> nestedAggs = AggregateSymbolCollectorVisitor.getAggregates(aggExp, true);
- if(nestedAggs.size() > 0) {
- handleValidationError(QueryPlugin.Util.getString("ERR.015.012.0039", nestedAggs), nestedAggs); //$NON-NLS-1$
- }
- }
+ validateNoNestedAggs(aggExp);
+ validateNoNestedAggs(obj.getOrderBy());
+ validateNoNestedAggs(obj.getCondition());
// Verify data type of aggregate expression
Type aggregateFunction = obj.getAggregateFunction();
@@ -91,6 +87,16 @@
}
validateBelow = false;
}
+
+ private void validateNoNestedAggs(LanguageObject aggExp) {
+ // Check for any nested aggregates (which are not allowed)
+ if(aggExp != null) {
+ Collection<AggregateSymbol> nestedAggs = AggregateSymbolCollectorVisitor.getAggregates(aggExp, true);
+ if(nestedAggs.size() > 0) {
+ handleValidationError(QueryPlugin.Util.getString("ERR.015.012.0039", nestedAggs), nestedAggs); //$NON-NLS-1$
+ }
+ }
+ }
public void visit(ElementSymbol obj) {
validateExpression(obj);
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-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -114,7 +114,6 @@
import org.teiid.query.sql.symbol.DerivedColumn;
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.Function;
import org.teiid.query.sql.symbol.GroupSymbol;
import org.teiid.query.sql.symbol.QueryString;
@@ -129,7 +128,6 @@
import org.teiid.query.sql.symbol.XMLParse;
import org.teiid.query.sql.symbol.XMLQuery;
import org.teiid.query.sql.symbol.AggregateSymbol.Type;
-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.EvaluatableVisitor;
@@ -208,18 +206,12 @@
public void visit(GroupBy obj) {
// Get list of all group by IDs
- List groupBySymbols = obj.getSymbols();
+ List<Expression> groupBySymbols = obj.getSymbols();
validateSortable(groupBySymbols);
- Iterator symbolIter = groupBySymbols.iterator();
- while(symbolIter.hasNext()) {
- SingleElementSymbol symbol = (SingleElementSymbol)symbolIter.next();
- if(symbol instanceof ExpressionSymbol) {
- ExpressionSymbol exprSymbol = (ExpressionSymbol) symbol;
- Expression expr = exprSymbol.getExpression();
- if (!ValueIteratorProviderCollectorVisitor.getValueIteratorProviders(expr).isEmpty() || expr instanceof Constant || expr instanceof Reference) {
- handleValidationError(QueryPlugin.Util.getString("ValidationVisitor.groupby_subquery", expr), expr); //$NON-NLS-1$
- }
- }
+ for (Expression expr : groupBySymbols) {
+ if (!ValueIteratorProviderCollectorVisitor.getValueIteratorProviders(expr).isEmpty() || expr instanceof Constant || expr instanceof Reference) {
+ handleValidationError(QueryPlugin.Util.getString("ValidationVisitor.groupby_subquery", expr), expr); //$NON-NLS-1$
+ }
}
}
@@ -666,15 +658,13 @@
* and ORDER BY.
* @param symbols List of SingleElementSymbol
*/
- protected void validateSortable(List symbols) {
- Iterator iter = symbols.iterator();
- while(iter.hasNext()) {
- SingleElementSymbol symbol = (SingleElementSymbol) iter.next();
- validateSortable(symbol);
+ protected void validateSortable(List<? extends Expression> symbols) {
+ for (Expression expression : symbols) {
+ validateSortable(expression);
}
}
- private void validateSortable(SingleElementSymbol symbol) {
+ private void validateSortable(Expression symbol) {
if (isNonComparable(symbol)) {
handleValidationError(QueryPlugin.Util.getString("ERR.015.012.0026", symbol), symbol); //$NON-NLS-1$
}
@@ -759,13 +749,16 @@
Select select = query.getSelect();
GroupBy groupBy = query.getGroupBy();
Criteria having = query.getHaving();
+ validateNoAggsInClause(groupBy);
+ validateNoAggsInClause(query.getCriteria());
+ validateNoAggsInClause(query.getFrom());
if(groupBy != null || having != null || !AggregateSymbolCollectorVisitor.getAggregates(select, false).isEmpty()) {
Set<Expression> groupSymbols = null;
if(groupBy != null) {
groupSymbols = new HashSet<Expression>();
- for (final Iterator iterator = groupBy.getSymbols().iterator(); iterator.hasNext();) {
- final SingleElementSymbol element = (SingleElementSymbol)iterator.next();
- groupSymbols.add(SymbolMap.getExpression(element));
+ for (final Iterator<Expression> iterator = groupBy.getSymbols().iterator(); iterator.hasNext();) {
+ final Expression element = iterator.next();
+ groupSymbols.add(element);
}
}
@@ -783,10 +776,20 @@
// Move items to this report
ValidatorReport report = visitor.getReport();
- Collection items = report.getItems();
+ Collection<ValidatorFailure> items = report.getItems();
super.getReport().addItems(items);
}
}
+
+ private void validateNoAggsInClause(LanguageObject clause) {
+ if (clause == null) {
+ return;
+ }
+ Collection<AggregateSymbol> aggs = AggregateSymbolCollectorVisitor.getAggregates(clause, false);
+ if (!aggs.isEmpty()) {
+ handleValidationError(QueryPlugin.Util.getString("SQLParser.Aggregate_only_top_level", aggs), aggs);
+ }
+ }
protected void validateInsert(Insert obj) {
Collection<ElementSymbol> vars = obj.getVariables();
@@ -1202,6 +1205,17 @@
@Override
public void visit(AggregateSymbol obj) {
+ if (obj.getCondition() != null) {
+ Expression condition = obj.getCondition();
+ if (!ValueIteratorProviderCollectorVisitor.getValueIteratorProviders(condition).isEmpty()) {
+ handleValidationError(QueryPlugin.Util.getString("ValidationVisitor.filter_subquery", condition), condition); //$NON-NLS-1$
+ }
+ for (ElementSymbol es : ElementCollectorVisitor.getElements(condition, false)) {
+ if (es.isExternalReference()) {
+ handleValidationError(QueryPlugin.Util.getString("ValidationVisitor.filter_subquery", es), es); //$NON-NLS-1$
+ }
+ }
+ }
if (obj.getAggregateFunction() != Type.TEXTAGG) {
return;
}
Modified: trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj
===================================================================
--- trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj 2011-07-20 03:27:02 UTC (rev 3317)
@@ -897,7 +897,7 @@
CriteriaSelector critSelector = new CriteriaSelector();
String element = null;
- List elements = new ArrayList();
+ List elements = new ArrayList(2);
Token operator = null;
}
{
@@ -1110,7 +1110,7 @@
[<WITH>
{
- critList = new ArrayList();
+ critList = new ArrayList(2);
}
<LPAREN>
element = id()
@@ -1481,8 +1481,9 @@
}]
(
- ( <VALUES>
- values = rowValues(info)
+ ( <VALUES> <LPAREN>
+ values = expressionList(info)
+ <RPAREN>
{
// Store each row of values
insert.setValues(values);
@@ -1544,13 +1545,12 @@
* @return List of values, never null
* @throws ParseException if parsing failed
*/
-List rowValues(ParseInfo info) :
+ArrayList<Expression> expressionList(ParseInfo info) :
{
- List rowVals = new ArrayList();
+ ArrayList<Expression> rowVals = new ArrayList<Expression>(4);
Expression value = null;
}
{
- <LPAREN>
value = expression(info)
{
rowVals.add(value);
@@ -1561,8 +1561,6 @@
rowVals.add(value);
}
)*
- <RPAREN>
-
{
return rowVals;
}
@@ -1822,7 +1820,6 @@
boolean isDistinct = false; // unless DISTINCT keyword in SELECT
SelectSymbol symbol = null;
Select select = new Select();
- info.aggregatesAllowed = true;
}
{
<SELECT>
@@ -1839,7 +1836,6 @@
)
)
{
- info.aggregatesAllowed = false;
select.setDistinct(isDistinct);
return select;
}
@@ -1924,55 +1920,30 @@
}
}
-AggregateSymbol xmlAgg(ParseInfo info) :
+AggregateSymbol orderedAgg(ParseInfo info) :
{
+ Token t = null;
Expression expression = null;
OrderBy orderBy = null;
+ Expression condition = null;
}
{
- <XMLAGG> <LPAREN>
+ (t=<XMLAGG>|t=<ARRAY_AGG>)
+ <LPAREN>
expression = expression(info)
- [
- orderBy = orderby(info)
- ]
+ [ orderBy = orderby(info) ]
<RPAREN>
+ condition = filterClause(info)
{
- if(! info.aggregatesAllowed) {
- throw new ParseException(QueryPlugin.Util.getString("SQLParser.Aggregate_only_top_level")); //$NON-NLS-1$
- }
-
- String name = generateFunctionName(info, "XMLAGG");
- AggregateSymbol agg = new AggregateSymbol(name, "XMLAGG", false, expression);
+ String aggName = t.image.toUpperCase();
+ String name = generateFunctionName(info, aggName);
+ AggregateSymbol agg = new AggregateSymbol(name, aggName, false, expression);
agg.setOrderBy(orderBy);
+ agg.setCondition(condition);
return agg;
}
}
-AggregateSymbol arrayAgg(ParseInfo info) :
-{
- Expression expression = null;
- OrderBy orderBy = null;
-}
-{
- <ARRAY_AGG> <LPAREN>
- expression = expression(info)
- [
- orderBy = orderby(info)
- ]
- <RPAREN>
- {
- if(! info.aggregatesAllowed) {
- throw new ParseException(QueryPlugin.Util.getString("SQLParser.Aggregate_only_top_level")); //$NON-NLS-1$
- }
-
- String name = generateFunctionName(info, "ARRAY_AGG");
- AggregateSymbol agg = new AggregateSymbol(name, "ARRAY_AGG", false, expression);
- agg.setOrderBy(orderBy);
- return agg;
- }
-}
-
-
AggregateSymbol textAgg(ParseInfo info) :
{
DerivedColumn expression = null;
@@ -1982,6 +1953,7 @@
List<DerivedColumn> expressions = new ArrayList<DerivedColumn>();
OrderBy orderBy = null;
String encoding = null;
+ Expression condition = null;
}
{
nonReserved("TEXTAGG") <LPAREN>
@@ -2015,20 +1987,18 @@
orderBy = orderby(info)
]
<RPAREN>
+ condition = filterClause(info)
{
- if(! info.aggregatesAllowed) {
- throw new ParseException(QueryPlugin.Util.getString("SQLParser.Aggregate_only_top_level")); //$NON-NLS-1$
- }
-
TextLine tf = new TextLine();
tf.setDelimiter(delimiter);
tf.setQuote(quote);
tf.setIncludeHeader(header);
tf.setExpressions(expressions);
tf.setEncoding(encoding);
- String name = generateFunctionName(info, "TEXTAGG");
+ String name = generateFunctionName(info, "TEXTAGG");
AggregateSymbol agg = new AggregateSymbol(name, "TEXTAGG", false, tf);
agg.setOrderBy(orderBy);
+ agg.setCondition(condition);
return agg;
}
}
@@ -2040,16 +2010,18 @@
AggregateSymbol agg = null;
boolean isDistinct = false;
Expression expression = null;
+ Expression condition = null;
}
{
(
// COUNT(*)
- LOOKAHEAD(3) (
+ (LOOKAHEAD(3) (
func = nonReserved("COUNT")
<LPAREN>
starToken = <STAR>
<RPAREN> ) |
-
+ LOOKAHEAD(<ID>, {matchesAny(getToken(1).image, "rank", "dense_rank", "row_number") != null}) (func = nonReserved("row_number", "rank", "dense_rank", "percent_rank", "cume_dist")
+ <LPAREN> <RPAREN>) |
// Remaining aggregates
( (func = nonReserved("COUNT", "SUM", "AVG", "MIN", "MAX", "EVERY", "STDDEV_POP", "STDDEV_SAMP", "VAR_SAMP", "VAR_POP")
|
@@ -2061,12 +2033,10 @@
[ <DISTINCT> {isDistinct=true;} | <ALL>]
expression = expression(info)
<RPAREN>
- )
+ ))
+ condition = filterClause(info)
)
{
- if(! info.aggregatesAllowed) {
- throw new ParseException(QueryPlugin.Util.getString("SQLParser.Aggregate_only_top_level")); //$NON-NLS-1$
- }
func = func.toUpperCase();
String name = generateFunctionName(info, func);
if(starToken == null) {
@@ -2076,10 +2046,22 @@
// COUNT(*)
agg = new AggregateSymbol(name, func, false, null);
}
+ agg.setCondition(condition);
return agg;
}
}
+Expression filterClause(ParseInfo info) :
+{
+ Expression condition = null;
+}
+{
+ [ <FILTER> <LPAREN> <WHERE> condition = booleanPrimary(info) <RPAREN> ]
+ {
+ return condition;
+ }
+}
+
/**
* <p>Parse a FROM. The from must handle groups, aliased groups or
* joined groups. This also handles JDBC escape processinf syntax for outer joins.</p>
@@ -2631,7 +2613,7 @@
*/
Criteria compoundCritOr(ParseInfo info) :
{
- ArrayList logicList = new ArrayList();
+ ArrayList logicList = new ArrayList(2);
Criteria logicPart = null;
}
{
@@ -2654,7 +2636,7 @@
*/
Criteria compoundCritAnd(ParseInfo info) :
{
- ArrayList logicList = new ArrayList();
+ ArrayList logicList = new ArrayList(2);
Criteria logicPart = null;
}
{
@@ -2677,14 +2659,20 @@
*/
Criteria notCrit(ParseInfo info) :
{
- Criteria crit = null;
+ Expression ex = null;
boolean isNot = false;
}
{
[<NOT> {isNot=true;}]
- crit=booleanPrimary(info)
+ ex=booleanPrimary(info)
{
+ Criteria crit = null;
+ if (ex instanceof Criteria) {
+ crit = (Criteria)ex;
+ } else {
+ crit = new ExpressionCriteria(ex);
+ }
if(isNot) {
return new NotCriteria(crit);
} else {
@@ -2698,38 +2686,30 @@
* @return criteria
* @throws ParseException if parsing failed
*/
-Criteria booleanPrimary(ParseInfo info) :
+Expression booleanPrimary(ParseInfo info) :
{
Expression ex = null;
- Criteria crit = null;
}
{
(
- LOOKAHEAD(2) crit = translateCriteria(info)
+ LOOKAHEAD(2) ex = translateCriteria(info)
|
(ex = commonValueExpression(info)
- {
- if (ex instanceof Criteria) {
- crit = (Criteria)ex;
- } else {
- crit = new ExpressionCriteria(ex);
- }
- }
[(
- LOOKAHEAD(2) crit=betweenCrit(info, ex) |
- LOOKAHEAD(2) crit=matchCrit(info, ex) |
- crit=setCrit(info, ex) |
- crit=isNullCrit(info, ex) |
- LOOKAHEAD(operator() (<ANY>|<SOME>|<ALL>) subquery(info)) crit=subqueryCompareCriteria(info, ex) |
- crit=compareCrit(info, ex)
+ LOOKAHEAD(2) ex=betweenCrit(info, ex) |
+ LOOKAHEAD(2) ex=matchCrit(info, ex) |
+ ex=setCrit(info, ex) |
+ ex=isNullCrit(info, ex) |
+ LOOKAHEAD(operator() (<ANY>|<SOME>|<ALL>) subquery(info)) ex=subqueryCompareCriteria(info, ex) |
+ ex=compareCrit(info, ex)
)]
)
|
- crit=existsCriteria(info) |
- crit = hasCriteria()
+ ex=existsCriteria(info) |
+ ex = hasCriteria()
)
{
- return crit;
+ return ex;
}
}
@@ -3018,53 +2998,17 @@
*/
GroupBy groupBy(ParseInfo info) :
{
- GroupBy groupBy = new GroupBy();
- SingleElementSymbol symbol = null;
+ List<Expression> expressions = null;
}
{
<GROUP> <BY>
- ( symbol = groupByItem(info)
- {
- groupBy.addSymbol(symbol);
- }
-
- (<COMMA> symbol = groupByItem(info)
- {
- groupBy.addSymbol(symbol);
- }
- )*
- )
+ expressions = expressionList(info)
{
- return groupBy;
+ return new GroupBy(expressions);
}
}
/**
- * <p>Parse a GROUP BY list item. </p>
- * @return Parsed group by item
- * @throws ParseException if parsing failed
- */
-SingleElementSymbol groupByItem(ParseInfo info) :
-{
- Expression expr = null;
- SingleElementSymbol symbol = null;
-}
-{
- expr = expression(info)
- {
- if(expr instanceof ElementSymbol) {
- symbol = (ElementSymbol) expr;
- } else {
- String exprName = generateFunctionName(info, null);
- symbol = new ExpressionSymbol(exprName, expr);
- }
- }
- {
- return symbol;
- }
-}
-
-/**
* <p>Parse a HAVING clause. </p>
* @return Parsed having
* @throws ParseException if parsing failed
@@ -3072,14 +3016,11 @@
Criteria having(ParseInfo info) :
{
Criteria criteria = null;
- info.aggregatesAllowed = true;
}
{
<HAVING>
criteria = criteria(info)
-
{
- info.aggregatesAllowed = false;
return criteria;
}
}
@@ -3438,19 +3379,20 @@
<RBRACE>
)
|
- LOOKAHEAD(<ID> <LPAREN> <FOR>) (expression=textAgg(info))
+ LOOKAHEAD(<ID> <LPAREN>, {matchesAny(getToken(1).image, "textagg") != null})
+ (expression=textAgg(info) [expression = windowSpecification(expression, info)])
|
// Aggregate function
- LOOKAHEAD(<ID>, {matchesAny(getToken(1).image, "count", "min", "max", "sum", "avg", "every", "STDDEV_POP", "STDDEV_SAMP", "VAR_SAMP", "VAR_POP") != null}) (expression=aggregateSymbol(info))
+ LOOKAHEAD(<ID> <LPAREN>, {matchesAny(getToken(1).image, "count", "min", "max", "sum", "avg", "every", "STDDEV_POP", "STDDEV_SAMP", "VAR_SAMP", "VAR_POP") != null})
+ (expression=aggregateSymbol(info) [expression = windowSpecification(expression, info)])
|
- LOOKAHEAD(<ANY>) (expression=aggregateSymbol(info))
+ LOOKAHEAD(<ANY>|<SOME>) (expression=aggregateSymbol(info) [expression = windowSpecification(expression, info)])
|
- LOOKAHEAD(<SOME>) (expression=aggregateSymbol(info))
+ expression=orderedAgg(info) [expression = windowSpecification(expression, info)]
|
- (expression=xmlAgg(info))
+ LOOKAHEAD(<ID> <LPAREN>, {matchesAny(getToken(1).image, "rank", "dense_rank", "row_number") != null})
+ (expression=aggregateSymbol(info) expression = windowSpecification(expression, info))
|
- (expression=arrayAgg(info))
- |
// Function
LOOKAHEAD(2) (expression=function(info))
|
@@ -3501,6 +3443,26 @@
}
}
+Expression windowSpecification(Expression agg, ParseInfo info) :
+{
+ List<Expression> partitionList = null;
+ OrderBy orderBy = null;
+}
+{
+ <OVER>
+ <LPAREN>
+ [<PARTITION> <BY> partitionList = expressionList(info)]
+ [orderBy = orderby(info)]
+ <RPAREN>
+ {
+ WindowFunction result = new WindowFunction();
+ result.setFunction((AggregateSymbol)agg);
+ result.setPartition(partitionList);
+ result.setOrderBy(orderBy);
+ return result;
+ }
+}
+
/**
* Parse a non-searched CASE expression.
* @return CaseExpression
@@ -3509,8 +3471,8 @@
CaseExpression caseExpression(ParseInfo info) :
{
Expression expression = null, whenExpression = null, thenExpression = null, elseExpression = null;
- ArrayList whenExpressions = new ArrayList();
- ArrayList thenExpressions = new ArrayList();
+ ArrayList whenExpressions = new ArrayList(2);
+ ArrayList thenExpressions = new ArrayList(2);
}
{
<CASE>
@@ -3543,8 +3505,8 @@
{
Expression thenExpression = null, elseExpression = null;
Criteria whenCriteria = null;
- ArrayList whenCriteriaList = new ArrayList();
- ArrayList thenExpressions = new ArrayList();
+ ArrayList whenCriteriaList = new ArrayList(2);
+ ArrayList thenExpressions = new ArrayList(2);
}
{
<CASE>
@@ -3578,7 +3540,7 @@
String funcName = null;
Expression expression = null;
- ArrayList args = new ArrayList();
+ ArrayList args = new ArrayList(2);
Token funcToken = null;
}
{
@@ -3665,62 +3627,16 @@
| funcToken = <YEAR> | funcToken = <MONTH> | funcToken = <HOUR>
| funcToken = <MINUTE> | funcToken = <SECOND> | funcToken = <XMLCONCAT>
| funcToken = <XMLCOMMENT>)
- <LPAREN>
- [
- expression = expression(info)
- {
- args.add(expression);
- expression = null;
- }
-
- (<COMMA> expression=expression(info)
- {
- args.add(expression);
- expression = null;
- }
- )*
- ]
+ <LPAREN>
+ [args = expressionList(info)]
<RPAREN>
)
|
- LOOKAHEAD(<INSERT> <LPAREN>) (
- (funcToken = <INSERT>)
+ LOOKAHEAD(<TRANSLATE>|<INSERT> <LPAREN>) (
+ (funcToken = <TRANSLATE> | funcToken = <INSERT>)
<LPAREN>
- [
- expression = expression(info)
- {
- args.add(expression);
- expression = null;
- }
-
- (<COMMA> expression=expression(info)
- {
- args.add(expression);
- expression = null;
- }
- )*
- ]
+ [args = expressionList(info)]
<RPAREN>
- )
- |
- LOOKAHEAD(<TRANSLATE> <LPAREN>) (
- (funcToken = <TRANSLATE>)
- <LPAREN>
- [
- expression = expression(info)
- {
- args.add(expression);
- expression = null;
- }
-
- (<COMMA> expression=expression(info)
- {
- args.add(expression);
- expression = null;
- }
- )*
- ]
- <RPAREN>
)
| expression = xmlParse(info)
{
@@ -3765,20 +3681,7 @@
|
( funcName = id()
<LPAREN>
- [
- expression = expression(info)
- {
- args.add(expression);
- expression = null;
- }
-
- (<COMMA> expression=expression(info)
- {
- args.add(expression);
- expression = null;
- }
- )*
- ]
+ [ args = expressionList(info) ]
<RPAREN>
))
{
@@ -3830,7 +3733,7 @@
{
Expression path = null;
DerivedColumn arg = null;
- ArrayList<DerivedColumn> args = new ArrayList<DerivedColumn>();
+ ArrayList<DerivedColumn> args = new ArrayList<DerivedColumn>(2);
}
{
nonReserved("QUERYSTRING") <LPAREN>
@@ -3850,7 +3753,7 @@
XMLElement xmlElement(ParseInfo info) :
{
String name = null;
- ArrayList content = new ArrayList();
+ ArrayList content = new ArrayList(2);
XMLNamespaces xmlNamespaces = null;
XMLAttributes xmlAttributes = null;
Expression expression = null;
@@ -3886,7 +3789,7 @@
XMLAttributes xmlAttributes(ParseInfo info) :
{
DerivedColumn expression = null;
- ArrayList<DerivedColumn> args = new ArrayList<DerivedColumn>();
+ ArrayList<DerivedColumn> args = new ArrayList<DerivedColumn>(2);
}
{
<XMLATTRIBUTES> <LPAREN>
@@ -3911,7 +3814,7 @@
{
DerivedColumn expression = null;
XMLNamespaces xmlNamespaces = null;
- ArrayList<DerivedColumn> args = new ArrayList<DerivedColumn>();
+ ArrayList<DerivedColumn> args = new ArrayList<DerivedColumn>(2);
}
{
<XMLFOREST> <LPAREN>
@@ -3939,7 +3842,7 @@
XMLNamespaces xmlNamespaces(ParseInfo info) :
{
- ArrayList namespaces = new ArrayList();
+ ArrayList namespaces = new ArrayList(2);
XMLNamespaces.NamespaceItem item = null;
}
{
Modified: trunk/engine/src/main/resources/org/teiid/query/i18n.properties
===================================================================
--- trunk/engine/src/main/resources/org/teiid/query/i18n.properties 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/main/resources/org/teiid/query/i18n.properties 2011-07-20 03:27:02 UTC (rev 3317)
@@ -259,7 +259,7 @@
SQLParser.Unknown_join_type=Unknown join type: {0}
-SQLParser.Aggregate_only_top_level=Aggregate expressions are allowed only as top level functions in the SELECT and HAVING clauses.
+SQLParser.Aggregate_only_top_level=Aggregate functions are not allowed in the FROM/WHERE/GROUP BY clauses: {0}
SQLParser.Unknown_agg_func=Unknown aggregate function: {0}
SQLParser.Invalid_func=Invalid function name: [{0}]
SQLParser.Integer_parse=Unable to parse integer literal: {0}
@@ -677,7 +677,8 @@
SimpleQueryResolver.procedure_cache_used=Procedure caching will be used for {0}.
SimpleQueryResolver.procedure_cache_not_usable=Procedure caching will not be used for {0} since the result set cache is disabled or the results/parameters cannot be cached.
SimpleQueryResolver.procedure_cache_not_used=Procedure caching will not be used for {0} due to the use of OPTION NOCACHE.
-ValidationVisitor.groupby_subquery=Expressions used in a GROUP BY cannot be constant and must not contain subqueries: "{0}".
+ValidationVisitor.groupby_subquery=Expressions used in a GROUP BY clause cannot be constant and must not contain subqueries: "{0}".
+ValidationVisitor.filter_subquery=Expressions used in a FILTER clause must not contain subqueries nor outer references: "{0}".
ValidationVisitor.Procedure_has_group_self_reference=Procedure cannot have a Group reference to itself.
ExpressionEvaluator.Expected_props_for_payload_function=Unable to evaluate {0}: expected Properties for command payload but got object of type {1}
ValidationVisitor.The_rowlimit_function_cannot_be_used_in_a_non-XML_command=The ''rowlimit'' and ''rowlimitexception'' functions cannot be used in a non-XML command
Modified: trunk/engine/src/test/java/org/teiid/dqp/internal/process/multisource/TestMultiSourcePlanToProcessConverter.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/dqp/internal/process/multisource/TestMultiSourcePlanToProcessConverter.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/test/java/org/teiid/dqp/internal/process/multisource/TestMultiSourcePlanToProcessConverter.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -35,7 +35,6 @@
import org.teiid.adminapi.impl.VDBMetaData;
import org.teiid.common.buffer.TupleSource;
import org.teiid.core.id.IDGenerator;
-import org.teiid.core.id.IntegerIDFactory;
import org.teiid.dqp.internal.process.DQPWorkContext;
import org.teiid.query.analysis.AnalysisRecord;
import org.teiid.query.metadata.QueryMetadataInterface;
@@ -113,7 +112,6 @@
CapabilitiesFinder finder = new MultiSourceCapabilitiesFinder(fakeFinder, multiSourceModels);
IDGenerator idGenerator = new IDGenerator();
- idGenerator.setDefaultFactory(new IntegerIDFactory());
Properties props = new Properties();
CommandContext context = new CommandContext("0", "test", "user", null, vdb.getName(), vdb.getVersion(), props, false); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
Modified: trunk/engine/src/test/java/org/teiid/query/optimizer/TestAggregatePushdown.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/optimizer/TestAggregatePushdown.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/test/java/org/teiid/query/optimizer/TestAggregatePushdown.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -69,7 +69,7 @@
String sql = "SELECT a12.intkey AS REGION_NBR, SUM(a11.intnum) AS WJXBFS1 FROM bqt1.smalla AS a11 INNER JOIN bqt2.smalla AS a12 ON a11.stringkey = a12.stringkey WHERE a11.stringkey = 0 GROUP BY a12.intkey"; //$NON-NLS-1$
ProcessorPlan plan = TestOptimizer.helpPlan(sql, RealMetadataFactory.exampleBQTCached(), null, capFinder,
- new String[] {"SELECT SUM(a11.intnum) FROM bqt1.smalla AS a11 WHERE a11.stringkey = '0' HAVING COUNT(*) > 0", "SELECT a12.intkey FROM bqt2.smalla AS a12 WHERE a12.stringkey = '0' group by a12.intkey"}, TestOptimizer.SHOULD_SUCCEED); //$NON-NLS-1$ //$NON-NLS-2$
+ new String[] {"SELECT SUM(a11.intnum) FROM bqt1.smalla AS a11 WHERE a11.stringkey = '0' HAVING COUNT(*) > 0", "SELECT a12.intkey FROM bqt2.smalla AS a12 WHERE a12.stringkey = '0'"}, TestOptimizer.SHOULD_SUCCEED); //$NON-NLS-1$ //$NON-NLS-2$
TestOptimizer.checkNodeTypes(plan, new int[] {
2, // Access
@@ -203,7 +203,7 @@
String sql = "select sum(a11.intnum) Profit, (sum(a11.intnum) / sum(a11.floatnum)) WJXBFS2 from bqt1.smalla a11 join bqt2.smallb a12 on a11.intkey=a12.intkey group by a12.intkey"; //$NON-NLS-1$
ProcessorPlan plan = TestOptimizer.helpPlan(sql, RealMetadataFactory.exampleBQTCached(), null, capFinder,
- new String[] {"SELECT g_0.intkey, SUM(g_0.intnum), SUM(g_0.floatnum) FROM bqt1.smalla AS g_0 GROUP BY g_0.intkey", "SELECT g_0.intkey FROM bqt2.smallb AS g_0 GROUP BY g_0.intkey"}, TestOptimizer.ComparisonMode.EXACT_COMMAND_STRING); //$NON-NLS-1$ //$NON-NLS-2$
+ new String[] {"SELECT g_0.intkey, SUM(g_0.intnum), SUM(g_0.floatnum) FROM bqt1.smalla AS g_0 GROUP BY g_0.intkey", "SELECT g_0.intkey FROM bqt2.smallb AS g_0"}, TestOptimizer.ComparisonMode.EXACT_COMMAND_STRING); //$NON-NLS-1$ //$NON-NLS-2$
TestOptimizer.checkNodeTypes(plan, new int[] {
2, // Access
@@ -298,7 +298,7 @@
String sql = "SELECT avg(y.e2) from pm1.g1 x, pm2.g1 y where x.e3 = y.e3 group by x.e2, y.e1"; //$NON-NLS-1$
ProcessorPlan plan = TestOptimizer.helpPlan(sql, RealMetadataFactory.example1Cached(), null, capFinder,
- new String[] {"SELECT g_0.e3, g_0.e2 FROM pm1.g1 AS g_0 GROUP BY g_0.e3, g_0.e2", "SELECT g_0.e3, g_0.e1, SUM(g_0.e2), COUNT(g_0.e2) FROM pm2.g1 AS g_0 GROUP BY g_0.e3, g_0.e1"}, TestOptimizer.ComparisonMode.EXACT_COMMAND_STRING); //$NON-NLS-1$ //$NON-NLS-2$
+ new String[] {"SELECT g_0.e3, g_0.e2 FROM pm1.g1 AS g_0", "SELECT g_0.e3, g_0.e1, SUM(g_0.e2), COUNT(g_0.e2) FROM pm2.g1 AS g_0 GROUP BY g_0.e3, g_0.e1"}, TestOptimizer.ComparisonMode.EXACT_COMMAND_STRING); //$NON-NLS-1$ //$NON-NLS-2$
TestOptimizer.checkNodeTypes(plan, new int[] {
2, // Access
@@ -317,7 +317,71 @@
0 // UnionAll
});
}
+
+ @Test public void testAvgAggregateFiltered() throws Exception {
+ FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
+ BasicSourceCapabilities caps = getAggregateCapabilities();
+ caps.setCapabilitySupport(Capability.QUERY_ORDERBY, false);
+ capFinder.addCapabilities("pm1", caps); //$NON-NLS-1$
+ capFinder.addCapabilities("pm2", caps); //$NON-NLS-1$
+
+ String sql = "SELECT avg(y.e2) filter (where y.e1 = 1) from pm1.g1 x, pm2.g1 y where x.e3 = y.e3 group by x.e2, y.e1"; //$NON-NLS-1$
+ ProcessorPlan plan = TestOptimizer.helpPlan(sql, RealMetadataFactory.example1Cached(), null, capFinder,
+ new String[] {"SELECT g_0.e3, g_0.e2 FROM pm1.g1 AS g_0",
+ "SELECT g_0.e3, g_0.e1, g_0.e2 FROM pm2.g1 AS g_0"}, TestOptimizer.ComparisonMode.EXACT_COMMAND_STRING); //$NON-NLS-1$ //$NON-NLS-2$
+
+ TestOptimizer.checkNodeTypes(plan, new int[] {
+ 2, // Access
+ 0, // DependentAccess
+ 0, // DependentSelect
+ 0, // DependentProject
+ 0, // DupRemove
+ 2, // Grouping
+ 0, // NestedLoopJoinStrategy
+ 1, // MergeJoinStrategy
+ 0, // Null
+ 0, // PlanExecution
+ 1, // Project
+ 0, // Select
+ 0, // Sort
+ 0 // UnionAll
+ });
+ }
+ /**
+ * Agg can only be computed after the join
+ */
+ @Test public void testAvgAggregateFiltered1() throws Exception {
+ FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
+ BasicSourceCapabilities caps = getAggregateCapabilities();
+ caps.setCapabilitySupport(Capability.ADVANCED_OLAP, true);
+ caps.setCapabilitySupport(Capability.QUERY_ORDERBY, false);
+ capFinder.addCapabilities("pm1", caps); //$NON-NLS-1$
+ capFinder.addCapabilities("pm2", caps); //$NON-NLS-1$
+
+ String sql = "SELECT avg(y.e2) filter (where x.e1 = 1) from pm1.g1 x, pm2.g1 y where x.e3 = y.e3 group by x.e2, y.e1"; //$NON-NLS-1$
+ ProcessorPlan plan = TestOptimizer.helpPlan(sql, RealMetadataFactory.example1Cached(), null, capFinder,
+ new String[] {"SELECT g_0.e3, g_0.e2, g_0.e1 FROM pm1.g1 AS g_0",
+ "SELECT g_0.e3, g_0.e1, g_0.e2 FROM pm2.g1 AS g_0"}, TestOptimizer.ComparisonMode.EXACT_COMMAND_STRING); //$NON-NLS-1$ //$NON-NLS-2$
+
+ TestOptimizer.checkNodeTypes(plan, new int[] {
+ 2, // Access
+ 0, // DependentAccess
+ 0, // DependentSelect
+ 0, // DependentProject
+ 0, // DupRemove
+ 1, // Grouping
+ 0, // NestedLoopJoinStrategy
+ 1, // MergeJoinStrategy
+ 0, // Null
+ 0, // PlanExecution
+ 1, // Project
+ 0, // Select
+ 0, // Sort
+ 0 // UnionAll
+ });
+ }
+
@Test public void testStddevAggregate() throws Exception {
FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
BasicSourceCapabilities caps = getAggregateCapabilities();
@@ -328,7 +392,7 @@
String sql = "SELECT stddev_pop(y.e2) from pm1.g1 x, pm2.g1 y where x.e3 = y.e3 group by x.e2, y.e1"; //$NON-NLS-1$
ProcessorPlan plan = TestOptimizer.helpPlan(sql, RealMetadataFactory.example1Cached(), null, capFinder,
- new String[] {"SELECT g_0.e3 AS c_0, g_0.e1 AS c_1, COUNT(g_0.e2) AS c_2, SUM(power(g_0.e2, 2)) AS c_3, SUM(g_0.e2) AS c_4 FROM pm2.g1 AS g_0 GROUP BY g_0.e3, g_0.e1 ORDER BY c_0", "SELECT g_0.e3 AS c_0, g_0.e2 AS c_1 FROM pm1.g1 AS g_0 GROUP BY g_0.e3, g_0.e2 ORDER BY c_0"}, TestOptimizer.ComparisonMode.EXACT_COMMAND_STRING); //$NON-NLS-1$ //$NON-NLS-2$
+ new String[] {"SELECT g_0.e3 AS c_0, g_0.e1 AS c_1, COUNT(g_0.e2) AS c_2, SUM(power(g_0.e2, 2)) AS c_3, SUM(g_0.e2) AS c_4 FROM pm2.g1 AS g_0 GROUP BY g_0.e3, g_0.e1 ORDER BY c_0", "SELECT g_0.e3 AS c_0, g_0.e2 AS c_1 FROM pm1.g1 AS g_0 ORDER BY c_0"}, TestOptimizer.ComparisonMode.EXACT_COMMAND_STRING); //$NON-NLS-1$ //$NON-NLS-2$
TestOptimizer.checkNodeTypes(plan, new int[] {
2, // Access
@@ -357,7 +421,7 @@
String sql = "SELECT count(y.e2) from pm1.g1 x, pm2.g1 y where x.e3 = y.e3 group by x.e2, y.e1"; //$NON-NLS-1$
ProcessorPlan plan = TestOptimizer.helpPlan(sql, RealMetadataFactory.example1Cached(), null, capFinder,
- new String[] {"SELECT g_0.e3, g_0.e2 FROM pm1.g1 AS g_0 GROUP BY g_0.e3, g_0.e2", "SELECT g_0.e3, g_0.e1, COUNT(g_0.e2) FROM pm2.g1 AS g_0 GROUP BY g_0.e3, g_0.e1"}, TestOptimizer.ComparisonMode.EXACT_COMMAND_STRING); //$NON-NLS-1$ //$NON-NLS-2$
+ new String[] {"SELECT g_0.e3, g_0.e2 FROM pm1.g1 AS g_0", "SELECT g_0.e3, g_0.e1, COUNT(g_0.e2) FROM pm2.g1 AS g_0 GROUP BY g_0.e3, g_0.e1"}, TestOptimizer.ComparisonMode.EXACT_COMMAND_STRING); //$NON-NLS-1$ //$NON-NLS-2$
TestOptimizer.checkNodeTypes(plan, new int[] {
2, // Access
@@ -767,8 +831,8 @@
ProcessorPlan plan = helpPlan(sql,
metadata,
null, capFinder,
- new String[] {"SELECT c2, c1, c0 FROM db2model.DB2TABLE", //$NON-NLS-1$
- "SELECT DISTINCT b2, sum(b0) FROM oraclemodel.OraTable GROUP BY b2 ORDER BY b2"}, //$NON-NLS-1$
+ new String[] {"SELECT g_0.c2, g_0.c1, g_0.c0 FROM db2model.DB2TABLE AS g_0", //$NON-NLS-1$
+ "SELECT g_0.b2 AS c_0, g_0.b0 AS c_1 FROM oraclemodel.OraTable AS g_0 ORDER BY c_0"}, //$NON-NLS-1$
SHOULD_SUCCEED );
checkNodeTypes(plan, new int[] {
@@ -777,12 +841,12 @@
0, // DependentSelect
0, // DependentProject
0, // DupRemove
- 1, // Grouping
+ 2, // Grouping
0, // NestedLoopJoinStrategy
1, // MergeJoinStrategy
0, // Null
0, // PlanExecution
- 2, // Project
+ 1, // Project
0, // Select
0, // Sort
0 // UnionAll
@@ -815,6 +879,90 @@
});
}
+ /**
+ * olap not supported
+ */
+ @Test public void testPushDownOverUnionFiltered() throws Exception {
+ FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
+ BasicSourceCapabilities caps = getAggregateCapabilities();
+ capFinder.addCapabilities("pm1", caps); //$NON-NLS-1$
+
+ ProcessorPlan plan = TestOptimizer.helpPlan("select e1, count(*) filter (where e3) from (select e1, e2, e3 from pm1.g1 union all select e1, e2, e3 from pm1.g2) y group by e1", RealMetadataFactory.example1Cached(), null, capFinder, //$NON-NLS-1$
+ new String[]{"SELECT g_0.e1, g_0.e3 FROM pm1.g1 AS g_0", "SELECT g_0.e1, g_0.e3 FROM pm1.g2 AS g_0"}, ComparisonMode.EXACT_COMMAND_STRING); //$NON-NLS-1$
+ TestOptimizer.checkNodeTypes(plan, new int[] {
+ 2, // Access
+ 0, // DependentAccess
+ 0, // DependentSelect
+ 0, // DependentProject
+ 0, // DupRemove
+ 1, // Grouping
+ 0, // NestedLoopJoinStrategy
+ 0, // MergeJoinStrategy
+ 0, // Null
+ 0, // PlanExecution
+ 1, // Project
+ 0, // Select
+ 0, // Sort
+ 1 // UnionAll
+ });
+ }
+
+ @Test public void testPushDownOverUnionFiltered1() throws Exception {
+ FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
+ BasicSourceCapabilities caps = getAggregateCapabilities();
+ caps.setCapabilitySupport(Capability.ADVANCED_OLAP, true);
+ capFinder.addCapabilities("pm1", caps); //$NON-NLS-1$
+
+ ProcessorPlan plan = TestOptimizer.helpPlan("select e1, count(*) filter (where e3) from (select e1, e2, e3 from pm1.g1 union all select e1, e2, e3 from pm1.g2) y group by e1", RealMetadataFactory.example1Cached(), null, capFinder, //$NON-NLS-1$
+ new String[]{"SELECT v_0.c_0, COUNT(*) FILTER(WHERE v_0.c_1) FROM (SELECT g_0.e1 AS c_0, g_0.e3 AS c_1 FROM pm1.g1 AS g_0) AS v_0 GROUP BY v_0.c_0",
+ "SELECT v_0.c_0, COUNT(*) FILTER(WHERE v_0.c_1) FROM (SELECT g_0.e1 AS c_0, g_0.e3 AS c_1 FROM pm1.g2 AS g_0) AS v_0 GROUP BY v_0.c_0"}, ComparisonMode.EXACT_COMMAND_STRING); //$NON-NLS-1$
+ TestOptimizer.checkNodeTypes(plan, new int[] {
+ 2, // Access
+ 0, // DependentAccess
+ 0, // DependentSelect
+ 0, // DependentProject
+ 0, // DupRemove
+ 1, // Grouping
+ 0, // NestedLoopJoinStrategy
+ 0, // MergeJoinStrategy
+ 0, // Null
+ 0, // PlanExecution
+ 1, // Project
+ 0, // Select
+ 0, // Sort
+ 1 // UnionAll
+ });
+ }
+
+ /**
+ * rand pushdown not supported
+ */
+ @Test public void testPushDownOverUnionFiltered3() throws Exception {
+ FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
+ BasicSourceCapabilities caps = getAggregateCapabilities();
+ caps.setCapabilitySupport(Capability.ADVANCED_OLAP, true);
+ capFinder.addCapabilities("pm1", caps); //$NON-NLS-1$
+
+ ProcessorPlan plan = TestOptimizer.helpPlan("select e1, count(*) filter (where e3 > rand()) from (select e1, e2, e3 from pm1.g1 union all select e1, e2, e3 from pm1.g2) y group by e1", RealMetadataFactory.example1Cached(), null, capFinder, //$NON-NLS-1$
+ new String[]{"SELECT g_0.e1, g_0.e3 FROM pm1.g1 AS g_0", "SELECT g_0.e1, g_0.e3 FROM pm1.g2 AS g_0"}, ComparisonMode.EXACT_COMMAND_STRING); //$NON-NLS-1$
+ TestOptimizer.checkNodeTypes(plan, new int[] {
+ 2, // Access
+ 0, // DependentAccess
+ 0, // DependentSelect
+ 0, // DependentProject
+ 0, // DupRemove
+ 1, // Grouping
+ 0, // NestedLoopJoinStrategy
+ 0, // MergeJoinStrategy
+ 0, // Null
+ 0, // PlanExecution
+ 1, // Project
+ 0, // Select
+ 0, // Sort
+ 1 // UnionAll
+ });
+ }
+
@Test public void testPushDownOverUnion1() throws Exception {
FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
BasicSourceCapabilities caps = getAggregateCapabilities();
@@ -908,7 +1056,7 @@
capFinder.addCapabilities("pm2", getAggregateCapabilities()); //$NON-NLS-1$
ProcessorPlan plan = TestOptimizer.helpPlan("select max(e2), case when e1 is null then 0 else 1 end from (select e1, e2 from pm1.g1 union all select e1, e2 from pm2.g2) z group by case when e1 is null then 0 else 1 end", RealMetadataFactory.example1Cached(), null, capFinder, //$NON-NLS-1$
- new String[]{"SELECT v_1.c_0, MAX(v_1.c_1) FROM (SELECT CASE WHEN v_0.c_0 IS NULL THEN 0 ELSE 1 END AS c_0, v_0.c_1 FROM (SELECT g_0.e1 AS c_0, g_0.e2 AS c_1 FROM pm1.g1 AS g_0) AS v_0) AS v_1 GROUP BY v_1.c_0", //$NON-NLS-1$
+ new String[]{"SELECT v_1.c_1, MAX(v_1.c_0) FROM (SELECT v_0.c_1 AS c_0, CASE WHEN v_0.c_0 IS NULL THEN 0 ELSE 1 END AS c_1 FROM (SELECT g_0.e1 AS c_0, g_0.e2 AS c_1 FROM pm1.g1 AS g_0) AS v_0) AS v_1 GROUP BY v_1.c_1", //$NON-NLS-1$
"SELECT g_0.e1, g_0.e2 FROM pm2.g2 AS g_0"}, ComparisonMode.EXACT_COMMAND_STRING); //$NON-NLS-1$
TestOptimizer.checkNodeTypes(plan, new int[] {
2, // Access
@@ -921,7 +1069,7 @@
0, // MergeJoinStrategy
0, // Null
0, // PlanExecution
- 3, // Project
+ 2, // Project
0, // Select
0, // Sort
1 // UnionAll
@@ -935,8 +1083,8 @@
capFinder.addCapabilities("pm1", caps); //$NON-NLS-1$
ProcessorPlan plan = TestOptimizer.helpPlan("select max(e2), case when e1 is null then 0 else 1 end from (select e1, e2, 1 as part from pm1.g1 union all select e1, e2, 2 as part from pm1.g2) z group by case when e1 is null then 0 else 1 end, part", RealMetadataFactory.example1Cached(), null, capFinder, //$NON-NLS-1$
- new String[]{"SELECT MAX(v_1.c_2), v_1.c_0 FROM (SELECT CASE WHEN v_0.c_0 IS NULL THEN 0 ELSE 1 END AS c_0, v_0.c_1, v_0.c_2 FROM (SELECT g_0.e1 AS c_0, 2 AS c_1, g_0.e2 AS c_2 FROM pm1.g2 AS g_0) AS v_0) AS v_1 GROUP BY v_1.c_0, v_1.c_1",
- "SELECT MAX(v_1.c_2), v_1.c_0 FROM (SELECT CASE WHEN v_0.c_0 IS NULL THEN 0 ELSE 1 END AS c_0, v_0.c_1, v_0.c_2 FROM (SELECT g_0.e1 AS c_0, 1 AS c_1, g_0.e2 AS c_2 FROM pm1.g1 AS g_0) AS v_0) AS v_1 GROUP BY v_1.c_0, v_1.c_1"}, ComparisonMode.EXACT_COMMAND_STRING); //$NON-NLS-1$
+ new String[]{"SELECT MAX(v_1.c_0), v_1.c_1 FROM (SELECT v_0.c_2 AS c_0, CASE WHEN v_0.c_0 IS NULL THEN 0 ELSE 1 END AS c_1, v_0.c_1 AS c_2 FROM (SELECT g_0.e1 AS c_0, 1 AS c_1, g_0.e2 AS c_2 FROM pm1.g1 AS g_0) AS v_0) AS v_1 GROUP BY v_1.c_1, v_1.c_2",
+ "SELECT MAX(v_1.c_0), v_1.c_1 FROM (SELECT v_0.c_2 AS c_0, CASE WHEN v_0.c_0 IS NULL THEN 0 ELSE 1 END AS c_1, v_0.c_1 AS c_2 FROM (SELECT g_0.e1 AS c_0, 2 AS c_1, g_0.e2 AS c_2 FROM pm1.g2 AS g_0) AS v_0) AS v_1 GROUP BY v_1.c_1, v_1.c_2"}, ComparisonMode.EXACT_COMMAND_STRING); //$NON-NLS-1$
TestOptimizer.checkNodeTypes(plan, new int[] {
2, // Access
0, // DependentAccess
Modified: trunk/engine/src/test/java/org/teiid/query/optimizer/TestExpressionsInGroupBy.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/optimizer/TestExpressionsInGroupBy.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/test/java/org/teiid/query/optimizer/TestExpressionsInGroupBy.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -32,10 +32,7 @@
/**
- * expressions in group use lacks robust support in MySQL, PostGres, and Derby Expressions and it's nothing more than syntactic sugar for an inline view,
- * a new approach was taken to use inline views rather than a non ANSI group by construct.
- *
- * Later we can add a connector binding property to support non-select expressions in group by.
+ * expressions in group use lacks robust support in MySQL, PostGres, and Derby, so a compensation step must be taken to create an inline view
*/
public class TestExpressionsInGroupBy {
@@ -57,7 +54,7 @@
// Plan query
ProcessorPlan plan = TestOptimizer.helpPlan(sql, RealMetadataFactory.exampleBQTCached(),
null, capFinder,
- new String[] { "SELECT convert(TimestampValue, date), COUNT(*) FROM bqt1.smalla GROUP BY convert(TimestampValue, date)" }, //$NON-NLS-1$
+ new String[] { "SELECT v_0.c_0, COUNT(*) FROM (SELECT convert(g_0.TimestampValue, date) AS c_0 FROM bqt1.smalla AS g_0) AS v_0 GROUP BY v_0.c_0" }, //$NON-NLS-1$
true);
TestOptimizer.checkNodeTypes(plan, TestOptimizer.FULL_PUSHDOWN);
}
@@ -81,7 +78,7 @@
// Plan query
ProcessorPlan plan = TestOptimizer.helpPlan(sql, RealMetadataFactory.exampleBQTCached(),
null, capFinder,
- new String[] { "SELECT convert(TimestampValue, date), COUNT(*) FROM bqt1.smalla GROUP BY convert(TimestampValue, date)" }, //$NON-NLS-1$
+ new String[] { "SELECT v_0.c_0, COUNT(*) FROM (SELECT convert(g_0.TimestampValue, date) AS c_0 FROM bqt1.smalla AS g_0) AS v_0 GROUP BY v_0.c_0" }, //$NON-NLS-1$
true);
TestOptimizer.checkNodeTypes(plan, TestOptimizer.FULL_PUSHDOWN);
}
@@ -105,7 +102,7 @@
0, // MergeJoinStrategy
0, // Null
0, // PlanExecution
- 2, // Project
+ 1, // Project
0, // Select
0, // Sort
0 // UnionAll
@@ -143,7 +140,7 @@
0, // MergeJoinStrategy
0, // Null
0, // PlanExecution
- 2, // Project
+ 1, // Project
0, // Select
0, // Sort
0 // UnionAll
@@ -181,7 +178,7 @@
0, // MergeJoinStrategy
0, // Null
0, // PlanExecution
- 2, // Project
+ 1, // Project
0, // Select
0, // Sort
0 // UnionAll
@@ -213,7 +210,7 @@
}
/**
- * Without inline view support the agg is not pushed down
+ * Without inline view support or functions in group by the agg is not pushed down
*/
@Test public void testFunctionInGroupBy() {
String sql = "SELECT sum (IntKey), case when IntKey>=5000 then '5000 +' else '0-999' end " + //$NON-NLS-1$
@@ -226,6 +223,7 @@
caps.setCapabilitySupport(Capability.QUERY_CASE, true);
caps.setCapabilitySupport(Capability.QUERY_SEARCHED_CASE, true);
caps.setCapabilitySupport(Capability.QUERY_AGGREGATES_SUM, true);
+ caps.setCapabilitySupport(Capability.QUERY_GROUP_BY, true);
caps.setCapabilitySupport(Capability.CRITERIA_COMPARE_ORDERED, true);
caps.setCapabilitySupport(Capability.CRITERIA_COMPARE_EQ, true);
capFinder.addCapabilities("BQT1", caps); //$NON-NLS-1$
@@ -233,7 +231,7 @@
ProcessorPlan plan = TestOptimizer.helpPlan(sql,
RealMetadataFactory.exampleBQTCached(),
null, capFinder,
- new String[] {"SELECT CASE WHEN BQT1.SmallA.IntKey >= 5000 THEN '5000 +' ELSE '0-999' END, BQT1.SmallA.IntKey FROM BQT1.SmallA"}, //$NON-NLS-1$
+ new String[] {"SELECT BQT1.SmallA.IntKey FROM BQT1.SmallA"}, //$NON-NLS-1$
TestOptimizer.SHOULD_SUCCEED );
TestOptimizer.checkNodeTypes(plan, new int[] {
@@ -254,6 +252,60 @@
});
}
+ @Test public void testFunctionInGroupBy1() {
+ String sql = "SELECT sum (IntKey), case when IntKey>=5000 then '5000 +' else '0-999' end " + //$NON-NLS-1$
+ "FROM BQT1.SmallA GROUP BY case when IntKey>=5000 then '5000 +' else '0-999' end"; //$NON-NLS-1$
+
+ // Plan query
+ FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
+ BasicSourceCapabilities caps = new BasicSourceCapabilities();
+ caps.setCapabilitySupport(Capability.QUERY_SELECT_EXPRESSION, true);
+ caps.setCapabilitySupport(Capability.QUERY_CASE, true);
+ caps.setCapabilitySupport(Capability.QUERY_SEARCHED_CASE, true);
+ caps.setCapabilitySupport(Capability.QUERY_AGGREGATES_SUM, true);
+ caps.setCapabilitySupport(Capability.QUERY_FUNCTIONS_IN_GROUP_BY, true);
+ caps.setCapabilitySupport(Capability.QUERY_GROUP_BY, true);
+ caps.setCapabilitySupport(Capability.CRITERIA_COMPARE_ORDERED, true);
+ caps.setCapabilitySupport(Capability.CRITERIA_COMPARE_EQ, true);
+ capFinder.addCapabilities("BQT1", caps); //$NON-NLS-1$
+
+ ProcessorPlan plan = TestOptimizer.helpPlan(sql,
+ RealMetadataFactory.exampleBQTCached(),
+ null, capFinder,
+ new String[] {"SELECT SUM(BQT1.SmallA.IntKey), CASE WHEN BQT1.SmallA.IntKey >= 5000 THEN '5000 +' ELSE '0-999' END FROM BQT1.SmallA GROUP BY CASE WHEN BQT1.SmallA.IntKey >= 5000 THEN '5000 +' ELSE '0-999' END"}, //$NON-NLS-1$
+ TestOptimizer.SHOULD_SUCCEED );
+
+ TestOptimizer.checkNodeTypes(plan, TestOptimizer.FULL_PUSHDOWN);
+ }
+
+ @Test public void testFunctionInGroupBy2() {
+ String sql = "SELECT sum (IntKey), case when IntKey>=5000 then '5000 +' else '0-999' end " + //$NON-NLS-1$
+ "FROM BQT1.SmallA GROUP BY case when IntKey>=5000 then '5000 +' else '0-999' end"; //$NON-NLS-1$
+
+ // Plan query
+ FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
+ BasicSourceCapabilities caps = new BasicSourceCapabilities();
+ caps.setCapabilitySupport(Capability.QUERY_SELECT_EXPRESSION, true);
+ caps.setCapabilitySupport(Capability.QUERY_CASE, true);
+ caps.setCapabilitySupport(Capability.QUERY_SEARCHED_CASE, true);
+ caps.setCapabilitySupport(Capability.QUERY_AGGREGATES_SUM, true);
+ caps.setCapabilitySupport(Capability.QUERY_FROM_INLINE_VIEWS, true);
+ caps.setCapabilitySupport(Capability.QUERY_GROUP_BY, true);
+ caps.setCapabilitySupport(Capability.QUERY_FROM_GROUP_ALIAS, true);
+ caps.setCapabilitySupport(Capability.CRITERIA_COMPARE_ORDERED, true);
+ caps.setCapabilitySupport(Capability.CRITERIA_COMPARE_EQ, true);
+ capFinder.addCapabilities("BQT1", caps); //$NON-NLS-1$
+
+ ProcessorPlan plan = TestOptimizer.helpPlan(sql,
+ RealMetadataFactory.exampleBQTCached(),
+ null, capFinder,
+ new String[] {"SELECT SUM(v_0.c_1), v_0.c_0 FROM (SELECT CASE WHEN g_0.IntKey >= 5000 THEN '5000 +' ELSE '0-999' END AS c_0, g_0.IntKey AS c_1 FROM BQT1.SmallA AS g_0) AS v_0 GROUP BY v_0.c_0"}, //$NON-NLS-1$
+ TestOptimizer.SHOULD_SUCCEED );
+
+ TestOptimizer.checkNodeTypes(plan, TestOptimizer.FULL_PUSHDOWN);
+ }
+
+
/**
* Test what happens when we have a CASE in the GROUP BY and source has aggregate capability but
* does not have CASE capability. Should not be able to push down GROUP BY.
@@ -291,7 +343,7 @@
0, // MergeJoinStrategy
0, // Null
0, // PlanExecution
- 2, // Project
+ 1, // Project
0, // Select
0, // Sort
0 // UnionAll
@@ -336,7 +388,7 @@
0, // MergeJoinStrategy
0, // Null
0, // PlanExecution
- 2, // Project
+ 1, // Project
1, // Select
0, // Sort
0 // UnionAll
@@ -378,7 +430,7 @@
0, // MergeJoinStrategy
0, // Null
0, // PlanExecution
- 2, // Project
+ 1, // Project
0, // Select
0, // Sort
0 // UnionAll
@@ -410,7 +462,7 @@
0, // MergeJoinStrategy
0, // Null
0, // PlanExecution
- 2, // Project
+ 1, // Project
1, // Select
0, // Sort
0 // UnionAll
@@ -442,7 +494,7 @@
0, // MergeJoinStrategy
0, // Null
0, // PlanExecution
- 2, // Project
+ 1, // Project
0, // Select
0, // Sort
0 // UnionAll
Modified: trunk/engine/src/test/java/org/teiid/query/optimizer/TestInlineView.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/optimizer/TestInlineView.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/test/java/org/teiid/query/optimizer/TestInlineView.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -25,6 +25,7 @@
import static org.teiid.query.optimizer.TestOptimizer.*;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -94,10 +95,8 @@
String userQuery = "select q1.a from (select count(bqt1.smalla.intkey) as a, bqt1.smalla.intkey from bqt1.smalla group by bqt1.smalla.intkey) q1 left outer join bqt1.smallb on q1.a = bqt1.smallb.intkey where q1.intkey = 1"; //$NON-NLS-1$
String optimizedQuery = "SELECT v_0.c_0 FROM (SELECT COUNT(g_0.intkey) AS c_0 FROM bqt1.smalla AS g_0 WHERE g_0.intkey = 1 GROUP BY g_0.intkey) AS v_0 LEFT OUTER JOIN bqt1.smallb AS g_1 ON v_0.c_0 = g_1.intkey"; //$NON-NLS-1$
- List expectedResults = new ArrayList();
- List row1 = new ArrayList();
- row1.add(new Integer(1));
- expectedResults.add(row1);
+ List<List<?>> expectedResults = new ArrayList<List<?>>();
+ expectedResults.add(Arrays.asList(1));
Set<String> sourceQueries = new HashSet<String>();
sourceQueries.add("oracle"); //$NON-NLS-1$
@@ -116,10 +115,8 @@
"where bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.intkey = 1 and bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa = bqt1.smallb.intkey"; //$NON-NLS-1$
String optimizedQuery = "SELECT v_0.c_0 FROM (SELECT COUNT(g_0.intkey) AS c_0 FROM bqt1.smalla AS g_0 WHERE g_0.intkey = 1 GROUP BY g_0.intkey) AS v_0, bqt1.smallb AS g_1 WHERE v_0.c_0 = g_1.intkey"; //$NON-NLS-1$
- List expectedResults = new ArrayList();
- List row1 = new ArrayList();
- row1.add(new Integer(1));
- expectedResults.add(row1);
+ List<List<?>> expectedResults = new ArrayList<List<?>>();
+ expectedResults.add(Arrays.asList(1));
Set<String> sourceQueries = new HashSet<String>();
sourceQueries.add("oracle"); //$NON-NLS-1$
@@ -134,12 +131,10 @@
public static InlineViewCase createInlineViewWithDistinctAndOrderBy() throws Exception {
String userQuery = "select Q1.a from (select distinct count(bqt1.smalla.intkey) as a, bqt1.smalla.intkey from bqt1.smalla group by bqt1.smalla.intkey order by bqt1.smalla.intkey) q1 inner join bqt1.smallb as q2 on q1.intkey = q2.intkey where q1.a = 1 and q1.a + q1.intkey = 2"; //$NON-NLS-1$
- String optimizedQuery = "SELECT v_0.c_1 FROM (SELECT g_0.intkey AS c_0, COUNT(g_0.intkey) AS c_1 FROM bqt1.smalla AS g_0 GROUP BY g_0.intkey HAVING ((COUNT(g_0.intkey) + g_0.intkey) = 2) AND (COUNT(g_0.intkey) = 1)) AS v_0, bqt1.smallb AS g_1 WHERE v_0.c_0 = g_1.intkey"; //$NON-NLS-1$
+ String optimizedQuery = "SELECT v_0.c_1 FROM (SELECT g_0.intkey AS c_0, COUNT(g_0.intkey) AS c_1 FROM bqt1.smalla AS g_0 GROUP BY g_0.intkey HAVING (COUNT(g_0.intkey) = 1) AND ((COUNT(g_0.intkey) + g_0.intkey) = 2)) AS v_0, bqt1.smallb AS g_1 WHERE v_0.c_0 = g_1.intkey"; //$NON-NLS-1$
- List expectedResults = new ArrayList();
- List row1 = new ArrayList();
- row1.add(new Integer(1));
- expectedResults.add(row1);
+ List<List<?>> expectedResults = new ArrayList<List<?>>();
+ expectedResults.add(Arrays.asList(1));
Set<String> sourceQueries = new HashSet<String>();
sourceQueries.add("oracle"); //$NON-NLS-1$
@@ -157,7 +152,7 @@
String userQuery = "select q1.A from (select count(intkey) as a, intkey, stringkey from vqt.smalla group by intkey, stringkey) q1 inner join vqt.smallb as q2 on q1.intkey = q2.a12345 where q1.a = 2"; //$NON-NLS-1$
String optimizedQuery = "SELECT v_0.c_1 FROM (SELECT g_0.IntKey AS c_0, COUNT(g_0.IntKey) AS c_1 FROM BQT1.SmallA AS g_0 GROUP BY g_0.IntKey, g_0.StringKey HAVING COUNT(g_0.IntKey) = 2) AS v_0, BQT1.SmallA AS g_1 WHERE v_0.c_0 = Concat(g_1.StringKey, g_1.StringNum)"; //$NON-NLS-1$
- List expectedResults = new ArrayList();
+ List<List<?>> expectedResults = new ArrayList<List<?>>();
Set<String> sourceQueries = new HashSet<String>();
sourceQueries.add("oracle"); //$NON-NLS-1$
@@ -172,12 +167,10 @@
public static InlineViewCase createInlineViewWithOuterOrderAndGroup() throws Exception {
String userQuery = "select count(Q1.a) b from (select distinct count(bqt1.smalla.intkey) as a, bqt1.smalla.intkey from bqt1.smalla group by bqt1.smalla.intkey order by bqt1.smalla.intkey) q1 inner join bqt1.smallb as q2 on q1.intkey = q2.intkey where q1.a = 1 and q1.a + q1.intkey = 2 group by Q1.a order by b"; //$NON-NLS-1$
- String optimizedQuery = "SELECT COUNT(v_0.c_1) AS c_0 FROM (SELECT g_0.intkey AS c_0, COUNT(g_0.intkey) AS c_1 FROM bqt1.smalla AS g_0 GROUP BY g_0.intkey HAVING ((COUNT(g_0.intkey) + g_0.intkey) = 2) AND (COUNT(g_0.intkey) = 1)) AS v_0, bqt1.smallb AS g_1 WHERE v_0.c_0 = g_1.intkey GROUP BY v_0.c_1 ORDER BY c_0"; //$NON-NLS-1$
+ String optimizedQuery = "SELECT COUNT(v_0.c_1) AS c_0 FROM (SELECT g_0.intkey AS c_0, COUNT(g_0.intkey) AS c_1 FROM bqt1.smalla AS g_0 GROUP BY g_0.intkey HAVING (COUNT(g_0.intkey) = 1) AND ((COUNT(g_0.intkey) + g_0.intkey) = 2)) AS v_0, bqt1.smallb AS g_1 WHERE v_0.c_0 = g_1.intkey GROUP BY v_0.c_1 ORDER BY c_0"; //$NON-NLS-1$
- List expectedResults = new ArrayList();
- List row1 = new ArrayList();
- row1.add(new Integer(1));
- expectedResults.add(row1);
+ List<List<?>> expectedResults = new ArrayList<List<?>>();
+ expectedResults.add(Arrays.asList(1));
Set<String> sourceQueries = new HashSet<String>();
sourceQueries.add("oracle"); //$NON-NLS-1$
@@ -192,15 +185,11 @@
public static InlineViewCase crateInlineViewsInUnions() throws Exception {
String userQuery = "select q1.a from (select count(bqt1.smalla.intkey) as a, bqt1.smalla.intkey from bqt1.smalla group by bqt1.smalla.intkey) q1 left outer join bqt1.smallb on q1.a = bqt1.smallb.intkey where q1.intkey = 1 union all (select count(Q1.a) b from (select distinct count(bqt1.smalla.intkey) as a, bqt1.smalla.intkey from bqt1.smalla group by bqt1.smalla.intkey order by bqt1.smalla.intkey) q1 inner join bqt1.smallb as q2 on q1.intkey = q2.intkey where q1.a = 1 and q1.a + q1.intkey = 2 group by Q1.a order by b)"; //$NON-NLS-1$
- String optimizedQuery = "SELECT v_1.c_0 FROM (SELECT COUNT(g_2.intkey) AS c_0 FROM bqt1.smalla AS g_2 WHERE g_2.intkey = 1 GROUP BY g_2.intkey) AS v_1 LEFT OUTER JOIN bqt1.smallb AS g_3 ON v_1.c_0 = g_3.intkey UNION ALL SELECT COUNT(v_0.c_1) AS c_0 FROM (SELECT g_0.IntKey AS c_0, COUNT(g_0.IntKey) AS c_1 FROM bqt1.smalla AS g_0 GROUP BY g_0.IntKey HAVING ((COUNT(g_0.IntKey) + g_0.IntKey) = 2) AND (COUNT(g_0.IntKey) = 1)) AS v_0, bqt1.smallb AS g_1 WHERE v_0.c_0 = g_1.intkey GROUP BY v_0.c_1"; //$NON-NLS-1$
+ String optimizedQuery = "SELECT v_1.c_0 FROM (SELECT COUNT(g_2.intkey) AS c_0 FROM bqt1.smalla AS g_2 WHERE g_2.intkey = 1 GROUP BY g_2.intkey) AS v_1 LEFT OUTER JOIN bqt1.smallb AS g_3 ON v_1.c_0 = g_3.intkey UNION ALL SELECT COUNT(v_0.c_1) AS c_0 FROM (SELECT g_0.IntKey AS c_0, COUNT(g_0.IntKey) AS c_1 FROM bqt1.smalla AS g_0 GROUP BY g_0.IntKey HAVING (COUNT(g_0.IntKey) = 1) AND ((COUNT(g_0.IntKey) + g_0.IntKey) = 2)) AS v_0, bqt1.smallb AS g_1 WHERE v_0.c_0 = g_1.intkey GROUP BY v_0.c_1"; //$NON-NLS-1$
- List expectedResults = new ArrayList();
- List row1 = new ArrayList();
- row1.add(new Integer(1));
- expectedResults.add(row1);
- List row2 = new ArrayList();
- row2.add(new Integer(1));
- expectedResults.add(row2);
+ List<List<?>> expectedResults = new ArrayList<List<?>>();
+ expectedResults.add(Arrays.asList(1));
+ expectedResults.add(Arrays.asList(2));
Set<String> sourceQueries = new HashSet<String>();
sourceQueries.add("oracle"); //$NON-NLS-1$
@@ -217,15 +206,11 @@
public static InlineViewCase createUnionInInlineView() throws Exception{
String userQuery = "select t1.intkey from (select case when q1.a=1 then 2 else 1 end as a from (select count(bqt1.smalla.intkey) as a, bqt1.smalla.intkey from bqt1.smalla group by bqt1.smalla.intkey) q1 left outer join bqt1.smallb on q1.a = bqt1.smallb.intkey where q1.intkey = 1 union all (select count(Q1.a) b from (select distinct count(bqt1.smalla.intkey) as a, bqt1.smalla.intkey from bqt1.smalla group by bqt1.smalla.intkey order by bqt1.smalla.intkey) q1 inner join bqt1.smallb as q2 on q1.intkey = q2.intkey where q1.a = 1 and q1.a + q1.intkey = 2 group by Q1.a order by b)) as q3, bqt1.smallb as t1 where q3.a = t1.intkey order by t1.intkey"; //$NON-NLS-1$
- String optimizedQuery = "SELECT g_4.intkey AS c_0 FROM (SELECT CASE WHEN v_1.c_0 = 1 THEN 2 ELSE 1 END AS c_0 FROM (SELECT COUNT(g_2.intkey) AS c_0 FROM bqt1.smalla AS g_2 WHERE g_2.intkey = 1 GROUP BY g_2.intkey) AS v_1 LEFT OUTER JOIN bqt1.smallb AS g_3 ON v_1.c_0 = g_3.intkey UNION ALL SELECT COUNT(v_0.c_1) AS c_0 FROM (SELECT g_0.IntKey AS c_0, COUNT(g_0.IntKey) AS c_1 FROM bqt1.smalla AS g_0 GROUP BY g_0.IntKey HAVING ((COUNT(g_0.IntKey) + g_0.IntKey) = 2) AND (COUNT(g_0.IntKey) = 1)) AS v_0, bqt1.smallb AS g_1 WHERE v_0.c_0 = g_1.intkey GROUP BY v_0.c_1) AS v_2, bqt1.smallb AS g_4 WHERE v_2.c_0 = g_4.intkey ORDER BY c_0"; //$NON-NLS-1$
+ String optimizedQuery = "SELECT g_4.intkey AS c_0 FROM (SELECT CASE WHEN v_1.c_0 = 1 THEN 2 ELSE 1 END AS c_0 FROM (SELECT COUNT(g_2.intkey) AS c_0 FROM bqt1.smalla AS g_2 WHERE g_2.intkey = 1 GROUP BY g_2.intkey) AS v_1 LEFT OUTER JOIN bqt1.smallb AS g_3 ON v_1.c_0 = g_3.intkey UNION ALL SELECT COUNT(v_0.c_1) AS c_0 FROM (SELECT g_0.IntKey AS c_0, COUNT(g_0.IntKey) AS c_1 FROM bqt1.smalla AS g_0 GROUP BY g_0.IntKey HAVING (COUNT(g_0.IntKey) = 1) AND ((COUNT(g_0.IntKey) + g_0.IntKey) = 2)) AS v_0, bqt1.smallb AS g_1 WHERE v_0.c_0 = g_1.intkey GROUP BY v_0.c_1) AS v_2, bqt1.smallb AS g_4 WHERE v_2.c_0 = g_4.intkey ORDER BY c_0"; //$NON-NLS-1$
- List expectedResults = new ArrayList();
- List row1 = new ArrayList();
- row1.add(new Integer(1));
- expectedResults.add(row1);
- List row2 = new ArrayList();
- row2.add(new Integer(2));
- expectedResults.add(row2);
+ List<List<?>> expectedResults = new ArrayList<List<?>>();
+ expectedResults.add(Arrays.asList(1));
+ expectedResults.add(Arrays.asList(2));
Set<String> sourceQueries = new HashSet<String>();
sourceQueries.add("oracle"); //$NON-NLS-1$
Modified: trunk/engine/src/test/java/org/teiid/query/optimizer/TestLimit.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/optimizer/TestLimit.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/test/java/org/teiid/query/optimizer/TestLimit.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -25,8 +25,7 @@
import java.util.Arrays;
import java.util.List;
-import junit.framework.TestCase;
-
+import org.junit.Test;
import org.teiid.core.types.DataTypeManager;
import org.teiid.metadata.Column;
import org.teiid.metadata.MetadataStore;
@@ -59,7 +58,7 @@
import org.teiid.query.unittest.RealMetadataFactory;
@SuppressWarnings("nls")
-public class TestLimit extends TestCase {
+public class TestLimit {
private static final int[] FULL_PUSHDOWN = new int[] {
1, // Access
@@ -97,10 +96,6 @@
UnionAllNode.class
};
- public TestLimit(String name) {
- super(name);
- }
-
private static TransformationMetadata exampleMetadata() {
MetadataStore metadataStore = new MetadataStore();
// Create models
@@ -157,7 +152,7 @@
return RealMetadataFactory.createTransformationMetadata(metadataStore, "example");
}
- public void testLimit() {
+ @Test public void testLimit() {
FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
BasicSourceCapabilities caps = new BasicSourceCapabilities();
capFinder.addCapabilities("pm1", caps); //$NON-NLS-1$
@@ -189,7 +184,7 @@
}, NODE_TYPES);
}
- public void testLimitPushdown() {
+ @Test public void testLimitPushdown() {
FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
BasicSourceCapabilities caps = new BasicSourceCapabilities();
caps.setCapabilitySupport(Capability.ROW_LIMIT, true);
@@ -205,7 +200,7 @@
TestOptimizer.checkNodeTypes(plan, FULL_PUSHDOWN, NODE_TYPES);
}
- public void testLimitWithOffset() {
+ @Test public void testLimitWithOffset() {
FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
BasicSourceCapabilities caps = new BasicSourceCapabilities();
capFinder.addCapabilities("pm1", caps); //$NON-NLS-1$
@@ -236,7 +231,7 @@
}, NODE_TYPES);
}
- public void testPushedLimitWithOffset() throws Exception {
+ @Test public void testPushedLimitWithOffset() throws Exception {
FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
BasicSourceCapabilities caps = new BasicSourceCapabilities();
caps.setCapabilitySupport(Capability.ROW_LIMIT, true);
@@ -268,7 +263,7 @@
}, NODE_TYPES);
}
- public void testLimitWithOffsetFullyPushed() {
+ @Test public void testLimitWithOffsetFullyPushed() {
FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
BasicSourceCapabilities caps = new BasicSourceCapabilities();
caps.setCapabilitySupport(Capability.ROW_LIMIT, true);
@@ -285,7 +280,7 @@
TestOptimizer.checkNodeTypes(plan, FULL_PUSHDOWN, NODE_TYPES);
}
- public void testSort() {
+ @Test public void testSort() {
FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
BasicSourceCapabilities caps = new BasicSourceCapabilities();
capFinder.addCapabilities("pm1", caps); //$NON-NLS-1$
@@ -316,7 +311,7 @@
}, NODE_TYPES);
}
- public void testSortPushed() {
+ @Test public void testSortPushed() {
FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
BasicSourceCapabilities caps = new BasicSourceCapabilities();
caps.setCapabilitySupport(Capability.QUERY_ORDERBY, true);
@@ -349,7 +344,7 @@
}, NODE_TYPES);
}
- public void testSortPushedWithLimit() {
+ @Test public void testSortPushedWithLimit() {
FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
BasicSourceCapabilities caps = new BasicSourceCapabilities();
caps.setCapabilitySupport(Capability.QUERY_ORDERBY, true);
@@ -367,7 +362,7 @@
TestOptimizer.checkNodeTypes(plan, FULL_PUSHDOWN, NODE_TYPES);
}
- public void testSortUnderLimitNotRemoved() {
+ @Test public void testSortUnderLimitNotRemoved() {
FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
BasicSourceCapabilities caps = new BasicSourceCapabilities();
// pm3 model supports order by
@@ -400,7 +395,7 @@
}
//TODO: there is a redundent project node here
- public void testSortAboveLimitNotPushed() {
+ @Test public void testSortAboveLimitNotPushed() {
FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
BasicSourceCapabilities caps = new BasicSourceCapabilities();
caps.setCapabilitySupport(Capability.QUERY_ORDERBY, true);
@@ -433,7 +428,7 @@
}, NODE_TYPES);
}
- public void testLimitNotPushedWithUnion() {
+ @Test public void testLimitNotPushedWithUnion() {
FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
BasicSourceCapabilities caps = new BasicSourceCapabilities();
caps.setCapabilitySupport(Capability.ROW_LIMIT, true);
@@ -466,7 +461,7 @@
}, NODE_TYPES);
}
- public void testLimitNotPushedWithDupRemove() {
+ @Test public void testLimitNotPushedWithDupRemove() {
FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
BasicSourceCapabilities caps = new BasicSourceCapabilities();
caps.setCapabilitySupport(Capability.ROW_LIMIT, true);
@@ -499,7 +494,7 @@
}, NODE_TYPES);
}
- public void testLimitPushedWithUnionAll() {
+ @Test public void testLimitPushedWithUnionAll() {
FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
BasicSourceCapabilities caps = new BasicSourceCapabilities();
caps.setCapabilitySupport(Capability.ROW_LIMIT, true);
@@ -532,7 +527,7 @@
}, NODE_TYPES);
}
- public void testLimitWithOffsetPushedWithUnion() throws Exception {
+ @Test public void testLimitWithOffsetPushedWithUnion() throws Exception {
FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
BasicSourceCapabilities caps = new BasicSourceCapabilities();
caps.setCapabilitySupport(Capability.ROW_LIMIT, true);
@@ -567,7 +562,7 @@
}, NODE_TYPES);
}
- public void testLimitNotPushedWithUnionOrderBy() {
+ @Test public void testLimitNotPushedWithUnionOrderBy() {
FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
BasicSourceCapabilities caps = new BasicSourceCapabilities();
caps.setCapabilitySupport(Capability.ROW_LIMIT, true);
@@ -601,7 +596,7 @@
TestOptimizer.checkNodeTypes(plan, new int[] {1}, new Class[]{DupRemoveSortNode.class});
}
- public void testCombinedLimits() throws Exception {
+ @Test public void testCombinedLimits() throws Exception {
FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
BasicSourceCapabilities caps = new BasicSourceCapabilities();
caps.setCapabilitySupport(Capability.ROW_LIMIT, true);
@@ -635,7 +630,7 @@
}, NODE_TYPES);
}
- public void testCombinedLimitsWithOffset() throws Exception {
+ @Test public void testCombinedLimitsWithOffset() throws Exception {
FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
BasicSourceCapabilities caps = new BasicSourceCapabilities();
caps.setCapabilitySupport(Capability.ROW_LIMIT, true);
@@ -654,7 +649,7 @@
TestOptimizer.checkNodeTypes(plan, FULL_PUSHDOWN, NODE_TYPES);
}
- public void testInlineView() {
+ @Test public void testInlineView() {
FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
BasicSourceCapabilities caps = new BasicSourceCapabilities();
//caps.setCapabilitySupport(SourceCapabilities.QUERY_ORDERBY, true);
@@ -682,7 +677,7 @@
*
* @since 4.3
*/
- public void testInlineViewAboveLimitNotMerged() {
+ @Test public void testInlineViewAboveLimitNotMerged() {
FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
BasicSourceCapabilities caps = new BasicSourceCapabilities();
caps.setCapabilitySupport(Capability.QUERY_ORDERBY, true);
@@ -706,7 +701,7 @@
* since there is no order by with the nested limit, the criteria can be pushed through
*
*/
- public void testCriteriaPushedUnderLimit() {
+ @Test public void testCriteriaPushedUnderLimit() {
FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
BasicSourceCapabilities caps = new BasicSourceCapabilities();
caps.setCapabilitySupport(Capability.ROW_LIMIT, true);
@@ -724,7 +719,7 @@
TestOptimizer.checkNodeTypes(plan, FULL_PUSHDOWN, NODE_TYPES);
}
- public void testInlineViewJoin() {
+ @Test public void testInlineViewJoin() {
FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
BasicSourceCapabilities caps = new BasicSourceCapabilities();
caps.setCapabilitySupport(Capability.QUERY_UNION, true);
@@ -768,7 +763,7 @@
});
}
- public void testDontPushSelectWithOrderedLimit() {
+ @Test public void testDontPushSelectWithOrderedLimit() {
FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
BasicSourceCapabilities caps = TestOptimizer.getTypicalCapabilities();
capFinder.addCapabilities("pm1", caps); //$NON-NLS-1$
@@ -798,7 +793,7 @@
}, NODE_TYPES);
}
- public void testDontPushSelectWithOrderedLimit1() {
+ @Test public void testDontPushSelectWithOrderedLimit1() {
FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
BasicSourceCapabilities caps = TestOptimizer.getTypicalCapabilities();
capFinder.addCapabilities("pm1", caps); //$NON-NLS-1$
@@ -828,7 +823,7 @@
}, NODE_TYPES);
}
- public void testLimitWithNoAccessNode() {
+ @Test public void testLimitWithNoAccessNode() {
String sql = "select 1 limit 1";//$NON-NLS-1$
String[] expectedSql = new String[] {};
@@ -856,7 +851,7 @@
/**
* Note here that the criteria made it to the having clause
*/
- public void testAggregateCriteriaOverUnSortedLimit() {
+ @Test public void testAggregateCriteriaOverUnSortedLimit() {
String sql = "select a from (SELECT MAX(e2) as a FROM pm1.g1 GROUP BY e2 LIMIT 1) x where a = 0"; //$NON-NLS-1$
FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
BasicSourceCapabilities caps = new BasicSourceCapabilities();
@@ -874,7 +869,7 @@
TestOptimizer.checkNodeTypes(plan, FULL_PUSHDOWN, NODE_TYPES);
}
- public void testSortWithLimitInlineView() {
+ @Test public void testSortWithLimitInlineView() {
String sql = "select e1 from (select pm1.g1.e1, pm1.g1.e2 from pm1.g1 order by pm1.g1.e1, pm1.g1.e2 limit 1) x"; //$NON-NLS-1$
ProcessorPlan plan = TestOptimizer.helpPlan(sql, RealMetadataFactory.example1Cached(), new String[] {"SELECT g_0.e1 AS c_0 FROM pm1.g1 AS g_0 ORDER BY c_0, g_0.e2"}); //$NON-NLS-1$
Modified: trunk/engine/src/test/java/org/teiid/query/optimizer/TestOptimizer.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/optimizer/TestOptimizer.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/test/java/org/teiid/query/optimizer/TestOptimizer.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -6286,7 +6286,7 @@
String sql = "select a.e1 from (select 1 e1) a, (select e1, 1 as a, x from (select e1, CASE WHEN e1 = 'a' THEN e2 ELSE e3 END as x from pm1.g2) y group by e1, x) b where a.e1 = b.x"; //$NON-NLS-1$
ProcessorPlan plan = helpPlan(sql, metadata, null, capFinder,
- new String[] {"SELECT v_1.c_0 FROM (SELECT v_0.c_1 AS c_0 FROM (SELECT g_0.e1 AS c_0, CASE WHEN g_0.e1 = 'a' THEN g_0.e2 ELSE g_0.e3 END AS c_1 FROM pm1.g2 AS g_0 WHERE CASE WHEN g_0.e1 = 'a' THEN g_0.e2 ELSE g_0.e3 END IN (<dependent values>)) AS v_0 GROUP BY v_0.c_0, v_0.c_1) AS v_1 ORDER BY c_0"}, ComparisonMode.EXACT_COMMAND_STRING); //$NON-NLS-1$
+ new String[] {"SELECT v_0.c_0 FROM (SELECT CASE WHEN g_0.e1 = 'a' THEN g_0.e2 ELSE g_0.e3 END AS c_0 FROM pm1.g2 AS g_0 GROUP BY g_0.e1, CASE WHEN g_0.e1 = 'a' THEN g_0.e2 ELSE g_0.e3 END) AS v_0 WHERE v_0.c_0 IN (<dependent values>) ORDER BY c_0"}, ComparisonMode.EXACT_COMMAND_STRING); //$NON-NLS-1$
checkNodeTypes(plan, new int[] {
0, // Access
Modified: trunk/engine/src/test/java/org/teiid/query/optimizer/xml/TestXMLPlanner.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/optimizer/xml/TestXMLPlanner.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/test/java/org/teiid/query/optimizer/xml/TestXMLPlanner.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -30,7 +30,6 @@
import org.teiid.core.TeiidComponentException;
import org.teiid.core.TeiidProcessingException;
import org.teiid.core.id.IDGenerator;
-import org.teiid.core.id.IntegerIDFactory;
import org.teiid.core.types.DataTypeManager;
import org.teiid.metadata.MetadataStore;
import org.teiid.metadata.Schema;
@@ -689,7 +688,6 @@
public static XMLPlan preparePlan(Command command, QueryMetadataInterface metadata, CapabilitiesFinder capFinder, CommandContext context)
throws QueryPlannerException, QueryMetadataException, TeiidComponentException {
IDGenerator idGenerator = new IDGenerator();
- idGenerator.setDefaultFactory(new IntegerIDFactory());
AnalysisRecord analysis = new AnalysisRecord(false, DEBUG);
try {
if (DEBUG) {
Modified: trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -117,6 +117,7 @@
import org.teiid.query.sql.symbol.TestCaseExpression;
import org.teiid.query.sql.symbol.TestSearchedCaseExpression;
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;
@@ -1413,28 +1414,12 @@
@Test public void testFailAliasInHaving() {
helpException("SELECT a FROM m.g GROUP BY a, b AS x"); //$NON-NLS-1$
}
-
- /** SELECT a FROM m.g GROUP BY count(a) */
- @Test public void testFailAggregateInGroupBy() {
- helpException("SELECT a FROM m.g GROUP BY count(a)"); //$NON-NLS-1$
- }
-
- @Test public void testExceptionLength() {
+ @Test(expected=QueryParserException.class) public void testExceptionLength() throws Exception {
String sql = "SELECT * FROM Customer where Customer.Name = (select lastname from CUSTOMER where acctid = 9"; ////$NON-NLS-1$
- try {
- QueryParser.getQueryParser().parseCommand(sql);
- fail("Expected exception for parsing " + sql); //$NON-NLS-1$
- } catch (TeiidException e) {
- //e.printStackTrace();
- //if (e.getMessage().length() > 1000) {
- // fail("Expected max length of message 1000; but received " + e.getMessage().length()); //$NON-NLS-1$
- //}
- }
+ QueryParser.getQueryParser().parseCommand(sql);
}
-
-
@Test public void testFunctionOfAggregates() {
GroupSymbol g = new GroupSymbol("m.g"); //$NON-NLS-1$
From from = new From();
@@ -6425,14 +6410,6 @@
}
}
- @Test public void testExceptionMessageWithoutLocation() {
- try {
- QueryParser.getQueryParser().parseCommand("SELECT COUNT(*) FROM a WHERE COUNT(*) > 1"); //$NON-NLS-1$
- } catch(QueryParserException e) {
- assertTrue(e.getMessage().startsWith("Parsing error: Aggregate expressions are allowed only as top level functions in the SELECT and HAVING clauses.")); //$NON-NLS-1$
- }
- }
-
@Test public void testEmptyOuterJoinCriteria() {
helpException("select a from b left outer join c on ()"); //$NON-NLS-1$
}
@@ -6852,5 +6829,34 @@
query.setSelect(new Select(Arrays.asList(new ExpressionSymbol("foo", new Reference(0)))));
helpTest(sql, "SELECT ?", query);
}
+
+ @Test public void testNonReserved() throws Exception {
+ String sql = "select count";
+ Query query = new Query();
+ query.setSelect(new Select(Arrays.asList(new ElementSymbol("count"))));
+ helpTest(sql, "SELECT count", query);
+ }
+
+ @Test public void testAggFilter() throws Exception {
+ String sql = "select count(*) filter (where x = 1) from g";
+ Query query = new Query();
+ AggregateSymbol aggregateSymbol = new AggregateSymbol("count", AggregateSymbol.Type.COUNT.name(), false, null);
+ aggregateSymbol.setCondition(new CompareCriteria(new ElementSymbol("x"), CompareCriteria.EQ, new Constant(1)));
+ query.setSelect(new Select(Arrays.asList(aggregateSymbol)));
+ query.setFrom(new From(Arrays.asList(new UnaryFromClause(new GroupSymbol("g")))));
+ helpTest(sql, "SELECT COUNT(*) FILTER(WHERE x = 1) FROM g", query);
+ }
+
+ @Test public void testWindowFunction() throws Exception {
+ String sql = "select row_number() over (partition by x order by y) from g";
+ Query query = new Query();
+ WindowFunction wf = new WindowFunction();
+ wf.setFunction(new AggregateSymbol("expr", "ROW_NUMBER", false, null));
+ wf.setPartition(new ArrayList<Expression>(Arrays.asList(new ElementSymbol("x"))));
+ wf.setOrderBy(new OrderBy(Arrays.asList(new ElementSymbol("y"))));
+ query.setSelect(new Select(Arrays.asList(new ExpressionSymbol("x", wf))));
+ query.setFrom(new From(Arrays.asList(new UnaryFromClause(new GroupSymbol("g")))));
+ helpTest(sql, "SELECT ROW_NUMBER() OVER (PARTITION BY x ORDER BY y) FROM g", query);
+ }
}
Modified: trunk/engine/src/test/java/org/teiid/query/processor/TestAggregateProcessing.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/TestAggregateProcessing.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/test/java/org/teiid/query/processor/TestAggregateProcessing.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -266,12 +266,12 @@
capFinder.addCapabilities("pm2", bac); //$NON-NLS-1$
HardcodedDataManager dataManager = new HardcodedDataManager();
- dataManager.addData("SELECT v_0.c_1, v_0.c_0, COUNT(*), MAX(v_0.c_2) FROM (SELECT g_0.e2 AS c_0, g_0.e1 AS c_1, g_0.e3 AS c_2 FROM pm1.g1 AS g_0) AS v_0 GROUP BY v_0.c_0, v_0.c_1", //$NON-NLS-1$
+ dataManager.addData("SELECT v_0.c_0, v_0.c_1, COUNT(*), MAX(v_0.c_2) FROM (SELECT g_0.e1 AS c_0, g_0.e2 AS c_1, g_0.e3 AS c_2 FROM pm1.g1 AS g_0) AS v_0 GROUP BY v_0.c_0, v_0.c_1", //$NON-NLS-1$
new List[] {
Arrays.asList("2", Integer.valueOf(2), Integer.valueOf(2), Boolean.FALSE), //$NON-NLS-1$
Arrays.asList("1", Integer.valueOf(1), Integer.valueOf(3), Boolean.TRUE), //$NON-NLS-1$
});
- dataManager.addData("SELECT v_0.c_1, v_0.c_0, COUNT(*), MAX(v_0.c_2) FROM (SELECT g_0.e2 AS c_0, convert(g_0.e2, string) AS c_1, g_0.e3 AS c_2 FROM pm2.g2 AS g_0 ORDER BY c_1 LIMIT 10) AS v_0 GROUP BY v_0.c_0, v_0.c_1", //$NON-NLS-1$
+ dataManager.addData("SELECT v_0.c_0, v_0.c_1, COUNT(*), MAX(v_0.c_2) FROM (SELECT convert(g_0.e2, string) AS c_0, g_0.e2 AS c_1, g_0.e3 AS c_2 FROM pm2.g2 AS g_0 ORDER BY c_0 LIMIT 10) AS v_0 GROUP BY v_0.c_0, v_0.c_1", //$NON-NLS-1$
new List[] {
Arrays.asList("1", Integer.valueOf(1), Integer.valueOf(4), Boolean.FALSE), //$NON-NLS-1$
});
@@ -360,9 +360,9 @@
List[] expected = new List[] {
Arrays.asList(null, "cc"),
Arrays.asList(0.0, "bb"),
- Arrays.asList(1.0, null),
- Arrays.asList(2.0, "aa"),
- Arrays.asList(7.0, "aa")
+ Arrays.asList(2.0, null),
+ Arrays.asList(21.0, "aa"),
+ Arrays.asList(24.0, "aa")
};
// Construct data manager with data
@@ -399,5 +399,25 @@
// Run query
helpProcess(plan, cc, dataManager, expected);
}
+
+ @Test public void testAggFilter() throws Exception {
+ // Create query
+ String sql = "SELECT e2, count(*) filter (where e3) from pm1.g1 group by e2 order by e2"; //$NON-NLS-1$
+ // Create expected results
+ List[] expected = new List[] {
+ Arrays.asList(0, 0),
+ Arrays.asList(1, 1),
+ Arrays.asList(2, 0),
+ Arrays.asList(3, 1),
+ };
+
+ // Construct data manager with data
+ FakeDataManager dataManager = new FakeDataManager();
+ sampleData1(dataManager);
+
+ ProcessorPlan plan = helpGetPlan(sql, RealMetadataFactory.example1Cached());
+ helpProcess(plan, dataManager, expected);
+ }
+
}
Modified: trunk/engine/src/test/java/org/teiid/query/processor/TestProcessor.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/TestProcessor.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/test/java/org/teiid/query/processor/TestProcessor.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -360,7 +360,7 @@
Properties props = new Properties();
props.setProperty("soap_host", "my.host.com"); //$NON-NLS-1$ //$NON-NLS-2$
props.setProperty("soap_port", "12345"); //$NON-NLS-1$ //$NON-NLS-2$
- CommandContext context = new CommandContext("0", "test", "user", null, "myvdb", 1, props, false); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ CommandContext context = new CommandContext("0", "test", "user", null, "myvdb", 1, props, DEBUG); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
context.setProcessorBatchSize(BufferManager.DEFAULT_PROCESSOR_BATCH_SIZE);
context.setConnectorBatchSize(BufferManager.DEFAULT_CONNECTOR_BATCH_SIZE);
context.setBufferManager(BufferManagerFactory.getStandaloneBufferManager());
@@ -7570,5 +7570,24 @@
helpProcess(plan, dataManager, new List[] {Arrays.asList(1, 1)});
}
+ @Test public void testOrderByExpression() throws Exception {
+ String sql = "SELECT pm1.g1.e2 as y FROM pm1.g1 ORDER BY e3 || e1";
+
+ List[] expected = new List[] {
+ Arrays.asList(0),
+ Arrays.asList(1),
+ Arrays.asList(3),
+ Arrays.asList(1),
+ Arrays.asList(2),
+ Arrays.asList(0),
+ };
+
+ FakeDataManager dataManager = new FakeDataManager();
+ sampleData1(dataManager);
+ ProcessorPlan plan = helpGetPlan(sql, RealMetadataFactory.example1Cached(), TestOptimizer.getGenericFinder());
+
+ helpProcess(plan, dataManager, expected);
+ }
+
private static final boolean DEBUG = false;
}
Modified: trunk/engine/src/test/java/org/teiid/query/processor/TestVirtualDepJoin.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/TestVirtualDepJoin.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/test/java/org/teiid/query/processor/TestVirtualDepJoin.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -364,7 +364,7 @@
List<String> expectedQueries = new ArrayList<String>(6);
for (int i = 0; i < 3; i++) {
expectedQueries.add("SELECT g_0.id AS c_0, g_0.first AS c_1, g_0.last AS c_2 FROM CustomerMaster.Customers AS g_0 WHERE g_0.first = 'Miles' ORDER BY c_0"); //$NON-NLS-1$
- expectedQueries.add("SELECT g_0.id AS c_0, g_0.amount AS c_1 FROM Europe.CustAccts AS g_0 WHERE g_0.id = 100 ORDER BY c_0"); //$NON-NLS-1$
+ expectedQueries.add("SELECT g_0.id, g_0.amount FROM Europe.CustAccts AS g_0 WHERE g_0.id = 100"); //$NON-NLS-1$
}
assertEquals(expectedQueries, dataManager.getQueries());
Modified: trunk/engine/src/test/java/org/teiid/query/sql/symbol/TestSearchedCaseExpression.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/sql/symbol/TestSearchedCaseExpression.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/test/java/org/teiid/query/sql/symbol/TestSearchedCaseExpression.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -25,16 +25,11 @@
import java.util.ArrayList;
import java.util.List;
+import junit.framework.TestCase;
+
import org.teiid.core.types.DataTypeManager;
import org.teiid.query.sql.lang.CompareCriteria;
-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.SearchedCaseExpression;
-
-import junit.framework.TestCase;
-
public class TestSearchedCaseExpression extends TestCase {
/**
Modified: trunk/engine/src/test/java/org/teiid/query/sql/visitor/TestExpressionMappingVisitor.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/sql/visitor/TestExpressionMappingVisitor.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/test/java/org/teiid/query/sql/visitor/TestExpressionMappingVisitor.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -45,7 +45,6 @@
import org.teiid.query.sql.symbol.SearchedCaseExpression;
import org.teiid.query.sql.symbol.TestCaseExpression;
import org.teiid.query.sql.symbol.TestSearchedCaseExpression;
-import org.teiid.query.sql.visitor.ExpressionMappingVisitor;
import org.teiid.translator.SourceSystemFunctions;
@@ -196,13 +195,13 @@
* a function.
*/
@Test public void testRecursionDetection() {
- ElementSymbol e1 = new ElementSymbol("e1"); //$NON-NLS-1$
+ ElementSymbol e1 = new ElementSymbol("g1.e1"); //$NON-NLS-1$
AggregateSymbol a1 = new AggregateSymbol("x", NonReserved.SUM, false, e1); //$NON-NLS-1$
Function f = new Function(SourceSystemFunctions.ADD_OP, new Expression[] {a1, a1});
HashMap<AggregateSymbol, AggregateSymbol> map = new HashMap<AggregateSymbol, AggregateSymbol>();
map.put(a1, new AggregateSymbol("x", NonReserved.SUM, false, a1)); //$NON-NLS-1$
ExpressionMappingVisitor.mapExpressions(f, map);
- assertEquals("(SUM(SUM(e1)) + SUM(SUM(e1)))", f.toString()); //$NON-NLS-1$
+ assertEquals("(SUM(SUM(g1.e1)) + SUM(SUM(g1.e1)))", f.toString()); //$NON-NLS-1$
}
}
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-19 13:41:13 UTC (rev 3316)
+++ trunk/engine/src/test/java/org/teiid/query/validator/TestValidator.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -1839,5 +1839,25 @@
models.add("MultiModel");
helpValidate("exec MultiModel.proc('a', (select 1))", new String[] {"MultiModel.proc.source_name"}, new MultiSourceMetadataWrapper(RealMetadataFactory.exampleMultiBinding(), models)); //$NON-NLS-1$
}
+
+ @Test public void testFailAggregateInGroupBy() {
+ helpValidate("SELECT max(e1) FROM pm1.g1 GROUP BY count(e2)", new String[] {"COUNT(e2)"}, RealMetadataFactory.example1Cached());
+ }
+
+ @Test public void testFailAggregateInWhere() {
+ helpValidate("SELECT e1 FROM pm1.g1 where count(e2) = 1", new String[] {"COUNT(e2)"}, RealMetadataFactory.example1Cached());
+ }
+ @Test public void testFailAggregateInFrom() {
+ helpValidate("SELECT g2.e1 FROM pm1.g1 inner join pm1.g2 on (avg(g1.e2) = g2.e2)", new String[] {"AVG(g1.e2)"}, RealMetadataFactory.example1Cached());
+ }
+
+ @Test public void testFailAggregateFilterSubquery() {
+ helpValidate("SELECT min(g1.e1) filter (where (select 1) = 1) from pm1.g1", new String[] {"(SELECT 1) = 1"}, RealMetadataFactory.example1Cached());
+ }
+
+ @Test public void testNestedAgg() {
+ helpValidate("SELECT min(g1.e1) filter (where max(e2) = 1) from pm1.g1", new String[] {"MAX(e2)"}, RealMetadataFactory.example1Cached());
+ }
+
}
Modified: trunk/test-integration/common/src/test/java/org/teiid/dqp/internal/process/TestTPCR.java
===================================================================
--- trunk/test-integration/common/src/test/java/org/teiid/dqp/internal/process/TestTPCR.java 2011-07-19 13:41:13 UTC (rev 3316)
+++ trunk/test-integration/common/src/test/java/org/teiid/dqp/internal/process/TestTPCR.java 2011-07-20 03:27:02 UTC (rev 3317)
@@ -191,7 +191,7 @@
ProcessorPlan plan = TestOptimizer.helpPlan("SELECT custsale.cntrycode, COUNT(*) AS numcust, SUM(c_acctbal) AS totacctbal FROM (SELECT left(C_PHONE, 2) AS cntrycode, CUSTOMER.C_ACCTBAL FROM CUSTOMER WHERE (left(C_PHONE, 2) IN ('13','31','23','29','30','18','17')) AND (CUSTOMER.C_ACCTBAL > (SELECT AVG(CUSTOMER.C_ACCTBAL) FROM CUSTOMER WHERE (CUSTOMER.C_ACCTBAL > 0.0) AND (left(C_PHONE, 2) IN ('13','31','23','29','30','18','17')))) AND (NOT (EXISTS (SELECT * FROM ORDERS WHERE O_CUSTKEY = C_CUSTKEY)))) AS custsale GROUP BY custsale.cntrycode ORDER BY custsale.cntrycode", //$NON-NLS-1$
METADATA, null, finder,
- new String[] {"SELECT v_0.c_0, COUNT(*) AS c_1, SUM(v_0.c_1) AS c_2 FROM (SELECT left(g_0.C_PHONE, 2) AS c_0, g_0.C_ACCTBAL AS c_1 FROM TPCR_Oracle_9i.CUSTOMER AS g_0 WHERE (left(g_0.C_PHONE, 2) IN ('13', '31', '23', '29', '30', '18', '17')) AND (g_0.C_ACCTBAL > (SELECT AVG(g_1.C_ACCTBAL) FROM TPCR_Oracle_9i.CUSTOMER AS g_1 WHERE (g_1.C_ACCTBAL > 0E-15) AND (left(g_1.C_PHONE, 2) IN ('13', '31', '23', '29', '30', '18', '17')))) AND (NOT EXISTS (SELECT 1 FROM TPCR_Oracle_9i.ORDERS AS g_2 WHERE g_2.O_CUSTKEY = g_0.C_CUSTKEY))) AS v_0 GROUP BY v_0.c_0 ORDER BY c_0 NULLS FIRST"}, ComparisonMode.EXACT_COMMAND_STRING); //$NON-NLS-1$
+ new String[] {"SELECT left(g_0.C_PHONE, 2) AS c_0, COUNT(*) AS c_1, SUM(g_0.C_ACCTBAL) AS c_2 FROM TPCR_Oracle_9i.CUSTOMER AS g_0 WHERE (left(g_0.C_PHONE, 2) IN ('13', '31', '23', '29', '30', '18', '17')) AND (g_0.C_ACCTBAL > (SELECT AVG(g_1.C_ACCTBAL) FROM TPCR_Oracle_9i.CUSTOMER AS g_1 WHERE (g_1.C_ACCTBAL > 0E-15) AND (left(g_1.C_PHONE, 2) IN ('13', '31', '23', '29', '30', '18', '17')))) AND (NOT EXISTS (SELECT 1 FROM TPCR_Oracle_9i.ORDERS AS g_2 WHERE g_2.O_CUSTKEY = g_0.C_CUSTKEY)) GROUP BY left(g_0.C_PHONE, 2) ORDER BY c_0 NULLS FIRST"}, ComparisonMode.EXACT_COMMAND_STRING); //$NON-NLS-1$
TestOptimizer.checkNodeTypes(plan, TestOptimizer.FULL_PUSHDOWN);
}
14 years, 5 months
teiid SVN: r3316 - in branches/7.4.x: engine and 3 other directories.
by teiid-commits@lists.jboss.org
Author: van.halbert
Date: 2011-07-19 09:41:13 -0400 (Tue, 19 Jul 2011)
New Revision: 3316
Modified:
branches/7.4.x/engine/pom.xml
branches/7.4.x/engine/src/main/java/org/teiid/query/xquery/saxon/DocumentWrapper.java
branches/7.4.x/engine/src/main/java/org/teiid/query/xquery/saxon/NodeWrapper.java
branches/7.4.x/engine/src/main/java/org/teiid/query/xquery/saxon/StreamingUtils.java
branches/7.4.x/engine/src/test/java/org/teiid/query/function/TestFunction.java
branches/7.4.x/engine/src/test/java/org/teiid/query/processor/TestSQLXMLProcessing.java
branches/7.4.x/pom.xml
Log:
SOA-3162 saxon upgrade - this is a 7.4.x update only, not for upstream at the moment
Modified: branches/7.4.x/engine/pom.xml
===================================================================
--- branches/7.4.x/engine/pom.xml 2011-07-18 14:45:50 UTC (rev 3315)
+++ branches/7.4.x/engine/pom.xml 2011-07-19 13:41:13 UTC (rev 3316)
@@ -78,14 +78,8 @@
<dependency>
<groupId>net.sourceforge.saxon</groupId>
- <artifactId>saxon</artifactId>
+ <artifactId>saxonhe</artifactId>
</dependency>
-
- <dependency>
- <groupId>net.sourceforge.saxon</groupId>
- <classifier>dom</classifier>
- <artifactId>saxon</artifactId>
- </dependency>
<dependency>
<groupId>com.googlecode.json-simple</groupId>
@@ -106,4 +100,4 @@
</dependencies>
-</project>
\ No newline at end of file
+</project>
Modified: branches/7.4.x/engine/src/main/java/org/teiid/query/xquery/saxon/DocumentWrapper.java
===================================================================
--- branches/7.4.x/engine/src/main/java/org/teiid/query/xquery/saxon/DocumentWrapper.java 2011-07-18 14:45:50 UTC (rev 3315)
+++ branches/7.4.x/engine/src/main/java/org/teiid/query/xquery/saxon/DocumentWrapper.java 2011-07-19 13:41:13 UTC (rev 3316)
@@ -115,7 +115,7 @@
* @return the unique number identifying this document within the name pool
*/
- public int getDocumentNumber() {
+ public long getDocumentNumber() {
return documentNumber;
}
@@ -124,12 +124,16 @@
*
* @param id
* the required ID value
+ * @param getParent
+ * true if running the element-with-id() function rather than the id()
+ * function; the difference is that in the case of an element of type xs:ID,
+ * the parent of the element should be returned, not the element itself.
* @return the element with the given ID, or null if there is no such ID
* present (or if the parser has not notified attributes as being of
* type ID).
*/
- public NodeInfo selectID(String id) {
+ public NodeInfo selectID(String id, boolean getParent) {
if (idIndex == null) {
Element elem;
switch (nodeKind) {
@@ -145,7 +149,14 @@
idIndex = new HashMap(50);
buildIDIndex(elem);
}
- return (NodeInfo) idIndex.get(id);
+
+ NodeInfo result = (NodeInfo) idIndex.get(id);
+
+ if (result != null && getParent && result.isId() && result.getStringValue().equals(id)) {
+ result = result.getParent();
+ }
+
+ return result ;
}
Modified: branches/7.4.x/engine/src/main/java/org/teiid/query/xquery/saxon/NodeWrapper.java
===================================================================
--- branches/7.4.x/engine/src/main/java/org/teiid/query/xquery/saxon/NodeWrapper.java 2011-07-18 14:45:50 UTC (rev 3315)
+++ branches/7.4.x/engine/src/main/java/org/teiid/query/xquery/saxon/NodeWrapper.java 2011-07-19 13:41:13 UTC (rev 3316)
@@ -160,6 +160,14 @@
}
/**
+ * Get the real XOM node, to implement the VirtualNode interface
+ */
+
+ public Object getRealNode() {
+ return node;
+ }
+
+ /**
* Get the name pool for this node
*
* @return the NamePool
@@ -799,7 +807,7 @@
* free-standing orphan node, just return the hashcode.
*/
- public int getDocumentNumber() {
+ public long getDocumentNumber() {
return docWrapper.getDocumentNumber();
}
Modified: branches/7.4.x/engine/src/main/java/org/teiid/query/xquery/saxon/StreamingUtils.java
===================================================================
--- branches/7.4.x/engine/src/main/java/org/teiid/query/xquery/saxon/StreamingUtils.java 2011-07-18 14:45:50 UTC (rev 3315)
+++ branches/7.4.x/engine/src/main/java/org/teiid/query/xquery/saxon/StreamingUtils.java 2011-07-19 13:41:13 UTC (rev 3316)
@@ -256,6 +256,7 @@
public void close() throws XPathException {
reciever.close();
+ super.close();
}
public void comment(CharSequence content, int locationId, int properties)
@@ -265,6 +266,7 @@
public void endDocument() throws XPathException {
reciever.endDocument();
+ super.endDocument() ;
}
public void endElement() throws XPathException {
@@ -285,6 +287,7 @@
}
public void open() throws XPathException {
+ super.open();
reciever.open();
}
@@ -295,10 +298,12 @@
public void setPipelineConfiguration(PipelineConfiguration config) {
reciever.setPipelineConfiguration(config);
+ super.setPipelineConfiguration(config);
}
public void setSystemId(String systemId) {
reciever.setSystemId(systemId);
+ super.setSystemId(systemId);
}
public void setUnparsedEntity(String name, String systemID,
@@ -311,6 +316,7 @@
}
public void startDocument(int properties) throws XPathException {
+ super.startDocument(properties);
reciever.startDocument(properties);
}
Modified: branches/7.4.x/engine/src/test/java/org/teiid/query/function/TestFunction.java
===================================================================
--- branches/7.4.x/engine/src/test/java/org/teiid/query/function/TestFunction.java 2011-07-18 14:45:50 UTC (rev 3315)
+++ branches/7.4.x/engine/src/test/java/org/teiid/query/function/TestFunction.java 2011-07-19 13:41:13 UTC (rev 3316)
@@ -1000,9 +1000,10 @@
}
@Test public void testTimestampDiffTimeStamp_Day_1() throws Exception {
+ // Moving to June, March fails because of DST
helpTestTimestampDiff(NonReserved.SQL_TSI_DAY,
- TimestampUtil.createTimestamp((2004-1900), 2, 1, 0, 0, 0, 0),
- TimestampUtil.createTimestamp((2004-1900), 3, 1, 0, 0, 0, 0),
+ TimestampUtil.createTimestamp((2004-1900), 4, 1, 0, 0, 0, 0),
+ TimestampUtil.createTimestamp((2004-1900), 5, 1, 0, 0, 0, 0),
new Long(31));
}
Modified: branches/7.4.x/engine/src/test/java/org/teiid/query/processor/TestSQLXMLProcessing.java
===================================================================
--- branches/7.4.x/engine/src/test/java/org/teiid/query/processor/TestSQLXMLProcessing.java 2011-07-18 14:45:50 UTC (rev 3315)
+++ branches/7.4.x/engine/src/test/java/org/teiid/query/processor/TestSQLXMLProcessing.java 2011-07-19 13:41:13 UTC (rev 3316)
@@ -202,8 +202,8 @@
String sql = "select * from xmltable('/a/b' passing convert('<a><b>first</b><b x=\"1\">second</b></a>', xml) columns val xml path '.') as x"; //$NON-NLS-1$
List<?>[] expected = new List<?>[] {
- Arrays.asList("<b>first</b>"),
- Arrays.asList("<b x=\"1\">second</b>"),
+ Arrays.asList("<b xmlns=\"\">first</b>"),
+ Arrays.asList("<b xmlns=\"\" x=\"1\">second</b>"),
};
process(sql, expected);
@@ -286,7 +286,7 @@
String sql = "select xmlquery('/a/b' passing xmlparse(document '<a><b x=''1''/><b x=''2''/></a>') null on empty)"; //$NON-NLS-1$
List<?>[] expected = new List<?>[] {
- Arrays.asList("<b x=\"1\"/><b x=\"2\"/>")
+ Arrays.asList("<b xmlns=\"\" x=\"1\"/><b xmlns=\"\" x=\"2\"/>")
};
process(sql, expected);
Modified: branches/7.4.x/pom.xml
===================================================================
--- branches/7.4.x/pom.xml 2011-07-18 14:45:50 UTC (rev 3315)
+++ branches/7.4.x/pom.xml 2011-07-19 13:41:13 UTC (rev 3316)
@@ -439,16 +439,10 @@
</dependency>
<dependency>
<groupId>net.sourceforge.saxon</groupId>
- <artifactId>saxon</artifactId>
- <version>9.1.0.8</version>
+ <artifactId>saxonhe</artifactId>
+ <version>9.2.1.5</version>
</dependency>
<dependency>
- <groupId>net.sourceforge.saxon</groupId>
- <artifactId>saxon</artifactId>
- <classifier>dom</classifier>
- <version>9.1.0.8</version>
- </dependency>
- <dependency>
<groupId>org.jboss.netty</groupId>
<artifactId>netty</artifactId>
<version>3.2.1.Final</version>
@@ -493,4 +487,4 @@
<url>https://repository.jboss.org/nexus/content/repositories/snapshots/</url>
</snapshotRepository>
</distributionManagement>
-</project>
\ No newline at end of file
+</project>
14 years, 5 months
teiid SVN: r3315 - trunk/connectors/translator-file/src/main/java/org/teiid/translator/file.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2011-07-18 10:45:50 -0400 (Mon, 18 Jul 2011)
New Revision: 3315
Modified:
trunk/connectors/translator-file/src/main/java/org/teiid/translator/file/FileExecutionFactory.java
Log:
removing nls warnings
Modified: trunk/connectors/translator-file/src/main/java/org/teiid/translator/file/FileExecutionFactory.java
===================================================================
--- trunk/connectors/translator-file/src/main/java/org/teiid/translator/file/FileExecutionFactory.java 2011-07-14 20:20:44 UTC (rev 3314)
+++ trunk/connectors/translator-file/src/main/java/org/teiid/translator/file/FileExecutionFactory.java 2011-07-18 14:45:50 UTC (rev 3315)
@@ -206,24 +206,24 @@
@Override
public void getMetadata(MetadataFactory metadataFactory, FileConnection connection) throws TranslatorException {
Procedure p = metadataFactory.addProcedure(GETTEXTFILES);
- p.setAnnotation("Returns text files that match the given path and pattern as CLOBs");
+ p.setAnnotation("Returns text files that match the given path and pattern as CLOBs"); //$NON-NLS-1$
ProcedureParameter param = metadataFactory.addProcedureParameter("pathAndPattern", TypeFacility.RUNTIME_NAMES.STRING, Type.In, p); //$NON-NLS-1$
- param.setAnnotation("The path and pattern of what files to return. Currently the only pattern supported is *.<ext>, which returns only the files matching the given extension at the given path.");
+ param.setAnnotation("The path and pattern of what files to return. Currently the only pattern supported is *.<ext>, which returns only the files matching the given extension at the given path."); //$NON-NLS-1$
metadataFactory.addProcedureResultSetColumn("file", TypeFacility.RUNTIME_NAMES.CLOB, p); //$NON-NLS-1$
metadataFactory.addProcedureResultSetColumn("filePath", TypeFacility.RUNTIME_NAMES.STRING, p); //$NON-NLS-1$
Procedure p1 = metadataFactory.addProcedure(GETFILES);
- p1.setAnnotation("Returns text files that match the given path and pattern as BLOBs");
+ p1.setAnnotation("Returns text files that match the given path and pattern as BLOBs"); //$NON-NLS-1$
param = metadataFactory.addProcedureParameter("pathAndPattern", TypeFacility.RUNTIME_NAMES.STRING, Type.In, p1); //$NON-NLS-1$
- param.setAnnotation("The path and pattern of what files to return. Currently the only pattern supported is *.<ext>, which returns only the files matching the given extension at the given path.");
+ param.setAnnotation("The path and pattern of what files to return. Currently the only pattern supported is *.<ext>, which returns only the files matching the given extension at the given path."); //$NON-NLS-1$
metadataFactory.addProcedureResultSetColumn("file", TypeFacility.RUNTIME_NAMES.BLOB, p1); //$NON-NLS-1$
metadataFactory.addProcedureResultSetColumn("filePath", TypeFacility.RUNTIME_NAMES.STRING, p1); //$NON-NLS-1$
Procedure p2 = metadataFactory.addProcedure(SAVEFILE);
- p2.setAnnotation("Saves the given vale to the given path. Any existing file will be overriden.");
+ p2.setAnnotation("Saves the given vale to the given path. Any existing file will be overriden."); //$NON-NLS-1$
metadataFactory.addProcedureParameter("filePath", TypeFacility.RUNTIME_NAMES.STRING, Type.In, p2); //$NON-NLS-1$
param = metadataFactory.addProcedureParameter("file", TypeFacility.RUNTIME_NAMES.OBJECT, Type.In, p2); //$NON-NLS-1$
- param.setAnnotation("The contents to save. Can be one of CLOB, BLOB, or XML");
+ param.setAnnotation("The contents to save. Can be one of CLOB, BLOB, or XML"); //$NON-NLS-1$
}
@Override
14 years, 5 months
teiid SVN: r3314 - in trunk/engine/src: main/java/org/teiid/query/rewriter and 2 other directories.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2011-07-14 16:20:44 -0400 (Thu, 14 Jul 2011)
New Revision: 3314
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/RuleRaiseAccess.java
trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
trunk/engine/src/main/java/org/teiid/query/sql/symbol/Reference.java
trunk/engine/src/test/java/org/teiid/query/rewriter/TestOrderByRewrite.java
Log:
TEIID-1667 preliminary change to simplify expression handling
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-14 14:31:30 UTC (rev 3313)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleMergeVirtual.java 2011-07-14 20:20:44 UTC (rev 3314)
@@ -126,9 +126,6 @@
for (ElementSymbol elementSymbol : elements) {
if (virtualGroup.equals(elementSymbol.getGroupSymbol())) {
unrelated = true;
- if (!(symbolMap.getMappedExpression(elementSymbol) instanceof ElementSymbol)) {
- return root;
- }
}
}
}
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleRaiseAccess.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleRaiseAccess.java 2011-07-14 14:31:30 UTC (rev 3313)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleRaiseAccess.java 2011-07-14 20:20:44 UTC (rev 3314)
@@ -344,7 +344,6 @@
List<OrderByItem> sortCols = ((OrderBy)parentNode.getProperty(NodeConstants.Info.SORT_ORDER)).getOrderByItems();
for (OrderByItem symbol : sortCols) {
- //TODO: this check shouldn't be necessary, since the order by is not introducing new expressions
if(! canPushSymbol(symbol.getSymbol(), true, modelID, metadata, capFinder, record)) {
return false;
}
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-14 14:31:30 UTC (rev 3313)
+++ trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java 2011-07-14 20:20:44 UTC (rev 3314)
@@ -903,57 +903,14 @@
LinkedList<OrderByItem> unrelatedItems = new LinkedList<OrderByItem>();
- boolean hasUnrelatedExpression = rewriteOrderBy(queryCommand, orderBy,
- projectedSymbols, unrelatedItems);
+ rewriteOrderBy(queryCommand, orderBy, projectedSymbols, unrelatedItems);
- if (orderBy.getVariableCount() == 0 || !hasUnrelatedExpression) {
- return queryCommand;
- }
-
- int originalSymbolCount = select.getProjectedSymbols().size();
-
- //add unrelated to select
- for (OrderByItem orderByItem : unrelatedItems) {
- select.addSymbol(orderByItem.getSymbol());
- }
- makeSelectUnique(select, false);
-
- Query query = queryCommand.getProjectedQuery();
-
- Into into = query.getInto();
- query.setInto(null);
- Limit limit = query.getLimit();
- query.setLimit(null);
- query.setOrderBy(null);
-
- Query top = null;
-
- try {
- top = createInlineViewQuery(new GroupSymbol("X"), query, metadata, select.getProjectedSymbols()); //$NON-NLS-1$
- Iterator<SingleElementSymbol> iter = top.getSelect().getProjectedSymbols().iterator();
- HashMap<Expression, SingleElementSymbol> expressionMap = new HashMap<Expression, SingleElementSymbol>();
- for (SingleElementSymbol symbol : select.getProjectedSymbols()) {
- SingleElementSymbol ses = iter.next();
- expressionMap.put(SymbolMap.getExpression(symbol), ses);
- expressionMap.put(new ElementSymbol(symbol.getName()), ses);
- }
- ExpressionMappingVisitor.mapExpressions(orderBy, expressionMap);
- //now the order by should only contain element symbols
- } catch (TeiidException err) {
- throw new TeiidRuntimeException(err);
- }
- List symbols = top.getSelect().getSymbols();
- top.getSelect().setSymbols(symbols.subList(0, originalSymbolCount));
- top.setInto(into);
- top.setLimit(limit);
- top.setOrderBy(orderBy);
- return top;
+ return queryCommand;
}
- public static boolean rewriteOrderBy(QueryCommand queryCommand,
+ public static void rewriteOrderBy(QueryCommand queryCommand,
final OrderBy orderBy, final List projectedSymbols,
LinkedList<OrderByItem> unrelatedItems) {
- boolean hasUnrelatedExpression = false;
HashSet<Expression> previousExpressions = new HashSet<Expression>();
for (int i = 0; i < orderBy.getVariableCount(); i++) {
SingleElementSymbol querySymbol = orderBy.getVariable(i);
@@ -970,14 +927,11 @@
orderBy.removeOrderByItem(i--);
} else if (!isUnrelated) {
orderBy.getOrderByItems().get(i).setSymbol((SingleElementSymbol)querySymbol.clone());
- } else {
- hasUnrelatedExpression = true;
}
}
if (orderBy.getVariableCount() == 0) {
queryCommand.setOrderBy(null);
}
- return hasUnrelatedExpression;
}
/**
Modified: trunk/engine/src/main/java/org/teiid/query/sql/symbol/Reference.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/symbol/Reference.java 2011-07-14 14:31:30 UTC (rev 3313)
+++ trunk/engine/src/main/java/org/teiid/query/sql/symbol/Reference.java 2011-07-14 20:20:44 UTC (rev 3314)
@@ -191,12 +191,4 @@
return this.positional;
}
- /**
- * Should never be called - used for an xml hack
- * @param expression
- */
- public void setExpression(ElementSymbol expression) {
- this.expression = expression;
- }
-
}
Modified: trunk/engine/src/test/java/org/teiid/query/rewriter/TestOrderByRewrite.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/rewriter/TestOrderByRewrite.java 2011-07-14 14:31:30 UTC (rev 3313)
+++ trunk/engine/src/test/java/org/teiid/query/rewriter/TestOrderByRewrite.java 2011-07-14 20:20:44 UTC (rev 3314)
@@ -305,11 +305,6 @@
new String[] { "pm1.g1.e1" } ); //$NON-NLS-1$
}
- @Test public void testOrderByExpression() throws Exception {
- Query resolvedQuery = (Query) getCommand("SELECT 0 AS SOMEINT, pm1.g1.e2 as y FROM pm1.g1 ORDER BY e2 || e1, e3"); //$NON-NLS-1$
- assertEquals("SELECT X.SOMEINT, X.y FROM (SELECT 0 AS SOMEINT, pm1.g1.e2 AS y, (e2 || e1) AS EXPR1, e3 FROM pm1.g1) AS X ORDER BY X.EXPR1, X.e3", resolvedQuery.toString()); //$NON-NLS-1$
- }
-
@Test public void testRewiteOrderBy() {
helpTestRewriteCommand("SELECT 1+1 as a FROM pm1.g1 order by a", "SELECT 2 AS a FROM pm1.g1"); //$NON-NLS-1$ //$NON-NLS-2$
}
14 years, 5 months
teiid SVN: r3313 - in branches/7.4.x: cache-jbosscache/src/main/java/org/teiid/cache/jboss and 1 other directory.
by teiid-commits@lists.jboss.org
Author: rareddy
Date: 2011-07-14 10:31:30 -0400 (Thu, 14 Jul 2011)
New Revision: 3313
Modified:
branches/7.4.x/build/kits/jboss-container/deploy/teiid/teiid-cache-manager-jboss-beans-rename-me.xml
branches/7.4.x/cache-jbosscache/src/main/java/org/teiid/cache/jboss/JBossCacheFactory.java
Log:
TEIID-1493: Replicate the cache contents when node joins the cluster
Modified: branches/7.4.x/build/kits/jboss-container/deploy/teiid/teiid-cache-manager-jboss-beans-rename-me.xml
===================================================================
--- branches/7.4.x/build/kits/jboss-container/deploy/teiid/teiid-cache-manager-jboss-beans-rename-me.xml 2011-07-14 14:07:35 UTC (rev 3312)
+++ branches/7.4.x/build/kits/jboss-container/deploy/teiid/teiid-cache-manager-jboss-beans-rename-me.xml 2011-07-14 14:31:30 UTC (rev 3313)
@@ -85,7 +85,7 @@
<!-- Hibernate 2LC can replicate custom types, so we use marshalling -->
<property name="useRegionBasedMarshalling">true</property>
<!-- Must match the value of "useRegionBasedMarshalling" -->
- <property name="inactiveOnStartup">true</property>
+ <property name="inactiveOnStartup">false</property>
<!-- Disable asynchronous RPC marshalling/sending -->
<property name="serializationExecutorPoolSize">0</property>
Modified: branches/7.4.x/cache-jbosscache/src/main/java/org/teiid/cache/jboss/JBossCacheFactory.java
===================================================================
--- branches/7.4.x/cache-jbosscache/src/main/java/org/teiid/cache/jboss/JBossCacheFactory.java 2011-07-14 14:07:35 UTC (rev 3312)
+++ branches/7.4.x/cache-jbosscache/src/main/java/org/teiid/cache/jboss/JBossCacheFactory.java 2011-07-14 14:31:30 UTC (rev 3313)
@@ -59,6 +59,7 @@
if (!this.cacheStore.getCacheStatus().allowInvocations()) {
this.cacheStore.start();
+ this.cacheStore.getRegion(this.cacheStore.getRoot().getFqn(), true).activate();
}
Node cacheRoot = this.cacheStore.getRoot().addChild(Fqn.fromString("Teiid")); //$NON-NLS-1$
@@ -67,6 +68,7 @@
Region cacheRegion = this.cacheStore.getRegion(node.getFqn(), true);
cacheRegion.setEvictionRegionConfig(buildEvictionConfig(node.getFqn(), config));
+ cacheRegion.activate();
JBossCache jc = null;
if (config != null && config.getPolicy().equals(Policy.EXPIRATION)) {
14 years, 5 months
teiid SVN: r3312 - in branches/as7: jboss-integration/src/main/java/org/teiid/jboss and 4 other directories.
by teiid-commits@lists.jboss.org
Author: rareddy
Date: 2011-07-14 10:07:35 -0400 (Thu, 14 Jul 2011)
New Revision: 3312
Added:
branches/as7/jboss-integration/src/main/java/org/teiid/jboss/SystemVDBService.java
Modified:
branches/as7/build/kits/jboss-as7/standalone/configuration/standalone-teiid.xml
branches/as7/jboss-integration/src/main/java/org/teiid/jboss/Configuration.java
branches/as7/jboss-integration/src/main/java/org/teiid/jboss/QueryEngineAdd.java
branches/as7/jboss-integration/src/main/java/org/teiid/jboss/TeiidServiceNames.java
branches/as7/jboss-integration/src/main/java/org/teiid/jboss/TeiidSubsystemParser.java
branches/as7/jboss-integration/src/test/resources/teiid-model-config.txt
branches/as7/jboss-integration/src/test/resources/teiid-sample-config.xml
branches/as7/metadata/src/main/java/org/teiid/metadata/index/IndexMetadataFactory.java
branches/as7/runtime/src/main/java/org/teiid/deployers/SystemVDBDeployer.java
branches/as7/runtime/src/main/java/org/teiid/deployers/VDBDeployer.java
branches/as7/test-integration/common/src/test/java/org/teiid/jdbc/TestLocalConnections.java
Log:
Added System VDB deployment
Modified: branches/as7/build/kits/jboss-as7/standalone/configuration/standalone-teiid.xml
===================================================================
--- branches/as7/build/kits/jboss-as7/standalone/configuration/standalone-teiid.xml 2011-07-13 20:34:20 UTC (rev 3311)
+++ branches/as7/build/kits/jboss-as7/standalone/configuration/standalone-teiid.xml 2011-07-14 14:07:35 UTC (rev 3312)
@@ -213,6 +213,7 @@
<module identifier="org.apache.aries.jmx" startlevel="2"/>
<module identifier="org.apache.felix.eventadmin" startlevel="2"/>
<module identifier="org.apache.felix.metatype" startlevel="2"/>
+ <module identifier="org.apache.felix.scr" startlevel="2"/>
<module identifier="org.apache.felix.webconsole" startlevel="2"/>
<module identifier="org.jboss.osgi.jmx" startlevel="2"/>
<module identifier="org.jboss.osgi.http" startlevel="2"/>
@@ -244,8 +245,8 @@
</subsystem>
<subsystem xmlns="urn:jboss:domain:teiid:1.0">
<query-engine>
- <thread-group-async>teiid-async</thread-group-async>
- <eventDistributorName>teiid/event-distributor</eventDistributorName>
+ <async-thread-group>teiid-async</async-thread-group>
+ <event-distributor-name>teiid/event-distributor</event-distributor-name>
<security-domain>teiid-security</security-domain>
<jdbc>
<socket-binding>teiid-jdbc</socket-binding>
Modified: branches/as7/jboss-integration/src/main/java/org/teiid/jboss/Configuration.java
===================================================================
--- branches/as7/jboss-integration/src/main/java/org/teiid/jboss/Configuration.java 2011-07-13 20:34:20 UTC (rev 3311)
+++ branches/as7/jboss-integration/src/main/java/org/teiid/jboss/Configuration.java 2011-07-14 14:07:35 UTC (rev 3312)
@@ -37,30 +37,30 @@
public static final String TRANSLATOR = "translator"; //$NON-NLS-1$
// Query-ENGINE
- public static final String ASYNC_THREAD_GROUP = "thread-group-async";//$NON-NLS-1$
- public static final String MAX_THREADS = "maxThreads";//$NON-NLS-1$
- public static final String MAX_ACTIVE_PLANS = "maxActivePlans";//$NON-NLS-1$
+ public static final String ASYNC_THREAD_GROUP = "async-thread-group";//$NON-NLS-1$
+ public static final String MAX_THREADS = "max-threads";//$NON-NLS-1$
+ public static final String MAX_ACTIVE_PLANS = "max-active-plans";//$NON-NLS-1$
public static final String USER_REQUEST_SOURCE_CONCURRENCY = "userRequestSourceConcurrency";//$NON-NLS-1$
- public static final String TIME_SLICE_IN_MILLI = "timeSliceInMilli";//$NON-NLS-1$
- public static final String MAX_ROWS_FETCH_SIZE = "maxRowsFetchSize";//$NON-NLS-1$
- public static final String LOB_CHUNK_SIZE_IN_KB = "lobChunkSizeInKB";//$NON-NLS-1$
- public static final String USE_DATA_ROLES = "useDataRoles";//$NON-NLS-1$
- public static final String ALLOW_CREATE_TEMPORY_TABLES_BY_DEFAULT = "allowCreateTemporaryTablesByDefault";//$NON-NLS-1$
- public static final String ALLOW_FUNCTION_CALLS_BY_DEFAULT = "allowFunctionCallsByDefault";//$NON-NLS-1$
- public static final String QUERY_THRESHOLD_IN_SECS = "queryThresholdInSecs";//$NON-NLS-1$
- public static final String MAX_SOURCE_ROWS = "maxSourceRows";//$NON-NLS-1$
- public static final String EXCEPTION_ON_MAX_SOURCE_ROWS = "exceptionOnMaxSourceRows";//$NON-NLS-1$
- public static final String MAX_ODBC_LOB_SIZE_ALLOWED = "maxODBCLobSizeAllowed";//$NON-NLS-1$
- public static final String EVENT_DISTRIBUTOR_NAME = "eventDistributorName";//$NON-NLS-1$
- public static final String DETECTING_CHANGE_EVENTS = "detectingChangeEvents";//$NON-NLS-1$
+ public static final String TIME_SLICE_IN_MILLI = "time-slice-in-millseconds";//$NON-NLS-1$
+ public static final String MAX_ROWS_FETCH_SIZE = "max-row-fetch-size";//$NON-NLS-1$
+ public static final String LOB_CHUNK_SIZE_IN_KB = "lob-chunk-size-in-kb";//$NON-NLS-1$
+ public static final String USE_DATA_ROLES = "use-dataroles";//$NON-NLS-1$
+ public static final String ALLOW_CREATE_TEMPORY_TABLES_BY_DEFAULT = "allow-creation-of-temporary-tables";//$NON-NLS-1$
+ public static final String ALLOW_FUNCTION_CALLS_BY_DEFAULT = "allow-function-calls";//$NON-NLS-1$
+ public static final String QUERY_THRESHOLD_IN_SECS = "query-threshold-in-seconds";//$NON-NLS-1$
+ public static final String MAX_SOURCE_ROWS = "max-source-rows-allowed";//$NON-NLS-1$
+ public static final String EXCEPTION_ON_MAX_SOURCE_ROWS = "exception-on-max-source-rows";//$NON-NLS-1$
+ public static final String MAX_ODBC_LOB_SIZE_ALLOWED = "max-odbc-lob-size-allowed";//$NON-NLS-1$
+ public static final String EVENT_DISTRIBUTOR_NAME = "event-distributor-name";//$NON-NLS-1$
+ public static final String DETECTING_CHANGE_EVENTS = "detect-change-events";//$NON-NLS-1$
public static final String SECURITY_DOMAIN = "security-domain";//$NON-NLS-1$
public static final String MAX_SESSIONS_ALLOWED = "max-sessions-allowed";//$NON-NLS-1$
public static final String SESSION_EXPIRATION_TIME_LIMIT = "sessions-expiration-timelimit";//$NON-NLS-1$
public static final String ALLOW_ENV_FUNCTION = "allow-env-function";//$NON-NLS-1$
- public static final String USE_DISK = "useDisk";//$NON-NLS-1$
- public static final String PROCESSOR_BATCH_SIZE = "processorBatchSize";//$NON-NLS-1$
- public static final String CONNECTOR_BATCH_SIZE = "connectorBatchSize";//$NON-NLS-1$
+ public static final String USE_DISK = "use-disk";//$NON-NLS-1$
+ public static final String PROCESSOR_BATCH_SIZE = "processor-batch-size";//$NON-NLS-1$
+ public static final String CONNECTOR_BATCH_SIZE = "connector-batch-size";//$NON-NLS-1$
public static final String MAX_RESERVE_BATCH_COLUMNS = "maxReserveBatchColumns";//$NON-NLS-1$
public static final String MAX_PROCESSING_BATCH_COLUMNS = "maxProcessingBatchesColumns";//$NON-NLS-1$
public static final String MAX_FILE_SIZE = "maxFileSize";//$NON-NLS-1$
Modified: branches/as7/jboss-integration/src/main/java/org/teiid/jboss/QueryEngineAdd.java
===================================================================
--- branches/as7/jboss-integration/src/main/java/org/teiid/jboss/QueryEngineAdd.java 2011-07-13 20:34:20 UTC (rev 3311)
+++ branches/as7/jboss-integration/src/main/java/org/teiid/jboss/QueryEngineAdd.java 2011-07-14 14:07:35 UTC (rev 3312)
@@ -45,6 +45,7 @@
import org.jboss.dmr.ModelNode;
import org.jboss.msc.inject.ConcurrentMapInjector;
import org.jboss.msc.service.*;
+import org.jboss.msc.value.InjectedValue;
import org.teiid.cache.CacheConfiguration;
import org.teiid.cache.CacheFactory;
import org.teiid.cache.DefaultCacheFactory;
@@ -78,6 +79,11 @@
final VDBRepository vdbRepo = buildVDBRepository(queryEngineNode);
final JBossLifeCycleListener shutdownListener = new JBossLifeCycleListener();
+ SystemVDBDeployer systemVDB = new SystemVDBDeployer();
+ systemVDB.setVDBRepository(vdbRepo);
+ SystemVDBService systemVDBService = new SystemVDBService(systemVDB);
+ newControllers.add(target.addService(TeiidServiceNames.SYSTEM_VDB, systemVDBService).install());
+
//FIXME *******************
final ObjectSerializer serializer = new ObjectSerializer("/tmp");
//FIXME *******************
@@ -86,7 +92,7 @@
TranslatorRepositoryService translatorService = new TranslatorRepositoryService(translatorRepo);
newControllers.add(target.addService(TeiidServiceNames.TRANSLATOR_REPO, translatorService).install());
- RelativePathService.addService(TeiidServiceNames.BUFFER_DIR, "teiid-buffer", "jboss.server.temp.dir", target); //$NON-NLS-1$ //$NON-NLS-2$
+ newControllers.add(RelativePathService.addService(TeiidServiceNames.BUFFER_DIR, "teiid-buffer", "jboss.server.temp.dir", target)); //$NON-NLS-1$ //$NON-NLS-2$
// TODO: remove verbose service by moving the buffer service from runtime project
final BufferServiceImpl bufferManager = buildBufferManager(queryEngineNode.get(Configuration.BUFFER_SERVICE));
@@ -133,7 +139,8 @@
serviceBuilder.addDependency(ServiceName.JBOSS.append("txn", "TransactionManager"), TransactionManager.class, engine.txnManagerInjector); //$NON-NLS-1$ //$NON-NLS-2$
serviceBuilder.addDependency(ServiceName.JBOSS.append("thread", "executor", asyncExecutor), Executor.class, engine.threadPoolInjector); //$NON-NLS-1$ //$NON-NLS-2$
serviceBuilder.addDependency(TeiidServiceNames.BUFFER_MGR, BufferServiceImpl.class, engine.bufferServiceInjector);
-
+ serviceBuilder.addDependency(TeiidServiceNames.SYSTEM_VDB, SystemVDBDeployer.class, new InjectedValue<SystemVDBDeployer>());
+
if (jdbc != null) {
serviceBuilder.addDependency(ServiceName.JBOSS.append("binding", jdbc.getSocketBinding()), SocketBinding.class, engine.jdbcSocketBindingInjector); //$NON-NLS-1$
}
Added: branches/as7/jboss-integration/src/main/java/org/teiid/jboss/SystemVDBService.java
===================================================================
--- branches/as7/jboss-integration/src/main/java/org/teiid/jboss/SystemVDBService.java (rev 0)
+++ branches/as7/jboss-integration/src/main/java/org/teiid/jboss/SystemVDBService.java 2011-07-14 14:07:35 UTC (rev 3312)
@@ -0,0 +1,52 @@
+/*
+ * 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.jboss;
+
+import org.jboss.msc.service.Service;
+import org.jboss.msc.service.StartContext;
+import org.jboss.msc.service.StartException;
+import org.jboss.msc.service.StopContext;
+import org.teiid.deployers.SystemVDBDeployer;
+
+public class SystemVDBService implements Service<SystemVDBDeployer> {
+ private SystemVDBDeployer deployer;
+
+ public SystemVDBService(SystemVDBDeployer deployer){
+ this.deployer = deployer;
+ }
+
+ @Override
+ public void start(StartContext context) throws StartException {
+ deployer.start();
+ }
+
+ @Override
+ public void stop(StopContext context) {
+ deployer.stop();
+ }
+
+ @Override
+ public SystemVDBDeployer getValue() throws IllegalStateException, IllegalArgumentException {
+ return deployer;
+ }
+
+}
Property changes on: branches/as7/jboss-integration/src/main/java/org/teiid/jboss/SystemVDBService.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Modified: branches/as7/jboss-integration/src/main/java/org/teiid/jboss/TeiidServiceNames.java
===================================================================
--- branches/as7/jboss-integration/src/main/java/org/teiid/jboss/TeiidServiceNames.java 2011-07-13 20:34:20 UTC (rev 3311)
+++ branches/as7/jboss-integration/src/main/java/org/teiid/jboss/TeiidServiceNames.java 2011-07-14 14:07:35 UTC (rev 3312)
@@ -29,6 +29,7 @@
static ServiceName TRANSLATOR_BASE = ServiceName.JBOSS.append("teiid", "translator");
public static ServiceName BUFFER_DIR = ServiceName.JBOSS.append("teiid", "buffer.dir");
public static ServiceName BUFFER_MGR = ServiceName.JBOSS.append("teiid", "buffer-mgr");
+ public static ServiceName SYSTEM_VDB = ServiceName.JBOSS.append("teiid", "system.vdb");
public static ServiceName translatorServiceName(String name) {
return TRANSLATOR_BASE.append(name);
Modified: branches/as7/jboss-integration/src/main/java/org/teiid/jboss/TeiidSubsystemParser.java
===================================================================
--- branches/as7/jboss-integration/src/main/java/org/teiid/jboss/TeiidSubsystemParser.java 2011-07-13 20:34:20 UTC (rev 3311)
+++ branches/as7/jboss-integration/src/main/java/org/teiid/jboss/TeiidSubsystemParser.java 2011-07-14 14:07:35 UTC (rev 3312)
@@ -45,25 +45,137 @@
@Override
public void writeContent(final XMLExtendedStreamWriter writer, final SubsystemMarshallingContext context) throws XMLStreamException {
context.startSubsystemElement(Namespace.CURRENT.getUri(), false);
- writer.writeStartElement(Configuration.QUERY_ENGINE);
-
ModelNode node = context.getModelNode();
- ModelNode teiidRuntime = node.require(Configuration.QUERY_ENGINE);
- //writeElement(writer, Element.batchSize, teiidRuntime.require("batch-size"));
-
- //writer.writeEndElement(); // End teiid-runtime element.
+ if (!node.isDefined()) {
+ return;
+ }
+ writer.writeStartElement(Element.QUERY_ENGINE_ELEMENT.getLocalName());
+ writeQueryEngine(writer, node);
+ writer.writeEndElement();
writer.writeEndElement(); // End of subsystem element
}
- private boolean has(ModelNode node, String name) {
+ // write the elements according to the schema defined.
+ private void writeQueryEngine( XMLExtendedStreamWriter writer, ModelNode node) throws XMLStreamException {
+ writeElement(writer, Element.ASYNC_THREAD_GROUP_ELEMENT, node);
+ writeElement(writer, Element.MAX_THREADS_ELEMENT, node);
+ writeElement(writer, Element.MAX_ACTIVE_PLANS_ELEMENT, node);
+ writeElement(writer, Element.USER_REQUEST_SOURCE_CONCURRENCY_ELEMENT, node);
+ writeElement(writer, Element.TIME_SLICE_IN_MILLI_ELEMENT, node);
+ writeElement(writer, Element.MAX_ROWS_FETCH_SIZE_ELEMENT, node);
+ writeElement(writer, Element.LOB_CHUNK_SIZE_IN_KB_ELEMENT, node);
+ writeElement(writer, Element.USE_DATA_ROLES_ELEMENT, node);
+ writeElement(writer, Element.ALLOW_CREATE_TEMPORY_TABLES_BY_DEFAULT_ELEMENT, node);
+ writeElement(writer, Element.ALLOW_FUNCTION_CALLS_BY_DEFAULT_ELEMENT, node);
+ writeElement(writer, Element.QUERY_THRESHOLD_IN_SECS_ELEMENT, node);
+ writeElement(writer, Element.MAX_SOURCE_ROWS_ELEMENT, node);
+ writeElement(writer, Element.EXCEPTION_ON_MAX_SOURCE_ROWS_ELEMENT, node);
+ writeElement(writer, Element.MAX_ODBC_LOB_SIZE_ALLOWED_ELEMENT, node);
+ writeElement(writer, Element.EVENT_DISTRIBUTOR_NAME_ELEMENT, node);
+ writeElement(writer, Element.DETECTING_CHANGE_EVENTS_ELEMENT, node);
+ writeElement(writer, Element.JDBC_SECURITY_DOMAIN_ELEMENT, node);
+ writeElement(writer, Element.MAX_SESSIONS_ALLOWED_ELEMENT, node);
+ writeElement(writer, Element.SESSION_EXPIRATION_TIME_LIMIT_ELEMENT, node);
+ writeElement(writer, Element.ALLOW_ENV_FUNCTION_ELEMENT, node);
+
+ if (has(node, Element.BUFFER_SERVICE_ELEMENT.getLocalName())){
+ writer.writeStartElement(Element.BUFFER_SERVICE_ELEMENT.getLocalName());
+ writeBufferService(writer, node.get(Element.BUFFER_SERVICE_ELEMENT.getLocalName()));
+ writer.writeEndElement();
+ }
+
+ if (has(node, Element.CACHE_FACORY_ELEMENT.getLocalName())){
+ writer.writeStartElement(Element.CACHE_FACORY_ELEMENT.getLocalName());
+ writeCacheFactoryConfiguration(writer, node.get(Element.CACHE_FACORY_ELEMENT.getLocalName()));
+ writer.writeEndElement();
+ }
+
+ if (has(node, Element.RESULTSET_CACHE_ELEMENT.getLocalName())){
+ writer.writeStartElement(Element.RESULTSET_CACHE_ELEMENT.getLocalName());
+ writeCacheConfiguration(writer, node.get(Element.RESULTSET_CACHE_ELEMENT.getLocalName()));
+ writer.writeEndElement();
+ }
+
+ if (has(node, Element.PREPAREDPLAN_CACHE_ELEMENT.getLocalName())){
+ writer.writeStartElement(Element.RESULTSET_CACHE_ELEMENT.getLocalName());
+ writeCacheConfiguration(writer, node.get(Element.PREPAREDPLAN_CACHE_ELEMENT.getLocalName()));
+ writer.writeEndElement();
+ }
+
+ //jdbc
+ if (has(node, Element.JDBC_ELEMENT.getLocalName())){
+ writer.writeStartElement(Element.JDBC_ELEMENT.getLocalName());
+ writeSocketConfiguration(writer, node.get(Element.JDBC_ELEMENT.getLocalName()));
+ writer.writeEndElement();
+ }
+
+ //odbc
+ if (has(node, Element.ODBC_ELEMENT.getLocalName())) {
+ writer.writeStartElement(Element.ODBC_ELEMENT.getLocalName());
+ writeSocketConfiguration(writer, node.get(Element.ODBC_ELEMENT.getLocalName()));
+ writer.writeEndElement();
+ }
+ }
+
+ private void writeSocketConfiguration(XMLExtendedStreamWriter writer, ModelNode node) throws XMLStreamException {
+ writeElement(writer, Element.MAX_SOCKET_SIZE_ELEMENT, node);
+ writeElement(writer, Element.IN_BUFFER_SIZE_ELEMENT, node);
+ writeElement(writer, Element.OUT_BUFFER_SIZE_ELEMENT, node);
+ writeElement(writer, Element.SOCKET_BINDING_ELEMENT, node);
+
+ if (has(node, Element.SSL_ELEMENT.getLocalName())) {
+ writer.writeStartElement(Element.SSL_ELEMENT.getLocalName());
+ writeSSLConfiguration(writer, node.get(Element.SSL_ELEMENT.getLocalName()));
+ writer.writeEndElement();
+ }
+ }
+
+ private void writeSSLConfiguration(XMLExtendedStreamWriter writer, ModelNode node) throws XMLStreamException {
+ writeElement(writer, Element.SSL_MODE_ELEMENT, node);
+ writeElement(writer, Element.KEY_STORE_FILE_ELEMENT, node);
+ writeElement(writer, Element.KEY_STORE_PASSWD_ELEMENT, node);
+ writeElement(writer, Element.KEY_STORE_TYPE_ELEMENT, node);
+ writeElement(writer, Element.SSL_PROTOCOL_ELEMENT, node);
+ writeElement(writer, Element.TRUST_FILE_ELEMENT, node);
+ writeElement(writer, Element.TRUST_PASSWD_ELEMENT, node);
+ writeElement(writer, Element.AUTH_MODE_ELEMENT, node);
+ writeElement(writer, Element.KEY_MANAGEMENT_ALG_ELEMENT, node);
+ }
+
+ private void writeBufferService(XMLExtendedStreamWriter writer, ModelNode node) throws XMLStreamException {
+ writeElement(writer, Element.USE_DISK_ELEMENT, node);
+ writeElement(writer, Element.PROCESSOR_BATCH_SIZE_ELEMENT, node);
+ writeElement(writer, Element.CONNECTOR_BATCH_SIZE_ELEMENT, node);
+ writeElement(writer, Element.MAX_RESERVE_BATCH_COLUMNS_ELEMENT, node);
+ writeElement(writer, Element.MAX_PROCESSING_BATCH_COLUMNS_ELEMENT, node);
+ writeElement(writer, Element.MAX_FILE_SIZE_ELEMENT, node);
+ writeElement(writer, Element.MAX_BUFFER_SPACE_ELEMENT, node);
+ writeElement(writer, Element.MAX_OPEN_FILES_ELEMENT, node);
+ }
+
+ private void writeCacheFactoryConfiguration(XMLExtendedStreamWriter writer, ModelNode node) throws XMLStreamException {
+ writeElement(writer, Element.CACHE_SERVICE_JNDI_NAME_ELEMENT, node);
+ writeElement(writer, Element.RESULTSET_CACHE_NAME_ELEMENT, node);
+ }
+
+ private void writeCacheConfiguration(XMLExtendedStreamWriter writer, ModelNode node) throws XMLStreamException {
+ writeElement(writer, Element.MAX_ENTRIES_ELEMENT, node);
+ writeElement(writer, Element.MAX_AGE_IN_SECS_ELEMENT, node);
+ writeElement(writer, Element.MAX_STALENESS_ELEMENT, node);
+ writeElement(writer, Element.CACHE_TYPE_ELEMENT, node);
+ writeElement(writer, Element.CACHE_LOCATION_ELEMENT, node);
+ }
+
+ private boolean has(ModelNode node, String name) {
return node.has(name) && node.get(name).isDefined();
}
- private void writeElement(final XMLExtendedStreamWriter writer, final Element element, final ModelNode value)
- throws XMLStreamException {
- writer.writeStartElement(element.getLocalName());
- writer.writeCharacters(value.asString());
- writer.writeEndElement();
+ private void writeElement(final XMLExtendedStreamWriter writer, final Element element, final ModelNode node) throws XMLStreamException {
+ if (has(node, element.getLocalName())) {
+ writer.writeStartElement(element.getLocalName());
+ writer.writeCharacters(node.get(element.getLocalName()).asString());
+ writer.writeEndElement();
+ }
}
@Override
@@ -88,12 +200,6 @@
switch (element) {
case QUERY_ENGINE_ELEMENT:
ModelNode node = parseQueryEngine(reader);
-// node.get(OP).set(ADD);
-// ModelNode nodeAddress = address.clone();
-// nodeAddress.add(Configuration.QUERY_ENGINE, "teiid-query-engine"); // should this be for each instance name? // //$NON-NLS-1$
-// nodeAddress.protect();
-// node.get(OP_ADDR).set(nodeAddress);
-// list.add(node);
subsystem.get(Configuration.QUERY_ENGINE).set(node);
break;
default:
Modified: branches/as7/jboss-integration/src/test/resources/teiid-model-config.txt
===================================================================
--- branches/as7/jboss-integration/src/test/resources/teiid-model-config.txt 2011-07-13 20:34:20 UTC (rev 3311)
+++ branches/as7/jboss-integration/src/test/resources/teiid-model-config.txt 2011-07-14 14:07:35 UTC (rev 3312)
@@ -1,12 +1,5 @@
{
"attributes" => {
- "jndi-name" => {
- "type" => STRING,
- "description" => "JNDI name of the Teiid Query Engine",
- "required" => true,
- "max-occurs" => 1,
- "default" => "teiid/engine-deployer"
- },
"thread-group-async" => {
"type" => STRING,
"description" => "Thread Pool to be used with Asynchronous operations in Teiid",
Modified: branches/as7/jboss-integration/src/test/resources/teiid-sample-config.xml
===================================================================
--- branches/as7/jboss-integration/src/test/resources/teiid-sample-config.xml 2011-07-13 20:34:20 UTC (rev 3311)
+++ branches/as7/jboss-integration/src/test/resources/teiid-sample-config.xml 2011-07-14 14:07:35 UTC (rev 3312)
@@ -1,5 +1,5 @@
<subsystem xmlns="urn:jboss:domain:teiid:1.0">
- <query-engine jndi-name="teiid/engine-deployer">
+ <query-engine>
<thread-group-async>teiid-async</thread-group-async>
<maxThreads>64</maxThreads>
<maxActivePlans>20</maxActivePlans>
Modified: branches/as7/metadata/src/main/java/org/teiid/metadata/index/IndexMetadataFactory.java
===================================================================
--- branches/as7/metadata/src/main/java/org/teiid/metadata/index/IndexMetadataFactory.java 2011-07-13 20:34:20 UTC (rev 3311)
+++ branches/as7/metadata/src/main/java/org/teiid/metadata/index/IndexMetadataFactory.java 2011-07-14 14:07:35 UTC (rev 3312)
@@ -24,10 +24,8 @@
import java.io.IOException;
import java.net.URISyntaxException;
-import java.net.URL;
import java.util.*;
-import org.jboss.vfs.VFS;
import org.jboss.vfs.VirtualFile;
import org.jboss.vfs.VirtualFileFilter;
import org.teiid.adminapi.impl.ModelMetaData;
@@ -71,8 +69,7 @@
* @throws IOException
* @throws URISyntaxException
*/
- public IndexMetadataFactory(URL url) throws IOException, URISyntaxException {
- VirtualFile vdb = VFS.getChild(url.toURI());
+ public IndexMetadataFactory(VirtualFile vdb) throws IOException, URISyntaxException {
List<VirtualFile> children = vdb.getChildrenRecursively(new VirtualFileFilter() {
@Override
public boolean accepts(VirtualFile file) {
Modified: branches/as7/runtime/src/main/java/org/teiid/deployers/SystemVDBDeployer.java
===================================================================
--- branches/as7/runtime/src/main/java/org/teiid/deployers/SystemVDBDeployer.java 2011-07-13 20:34:20 UTC (rev 3311)
+++ branches/as7/runtime/src/main/java/org/teiid/deployers/SystemVDBDeployer.java 2011-07-14 14:07:35 UTC (rev 3312)
@@ -21,11 +21,15 @@
*/
package org.teiid.deployers;
+import java.io.Closeable;
import java.io.IOException;
-import java.net.URI;
+import java.io.InputStream;
import java.net.URISyntaxException;
-import java.net.URL;
+import org.jboss.as.server.deployment.module.TempFileProviderService;
+import org.jboss.modules.Module;
+import org.jboss.vfs.VFS;
+import org.jboss.vfs.VirtualFile;
import org.teiid.core.CoreConstants;
import org.teiid.core.TeiidRuntimeException;
import org.teiid.metadata.index.IndexMetadataFactory;
@@ -35,17 +39,21 @@
public class SystemVDBDeployer {
private VDBRepository vdbRepository;
-
+ private Closeable file;
public void start() {
try {
- URL url = Thread.currentThread().getContextClassLoader().getResource(CoreConstants.SYSTEM_VDB);
- if (url == null) {
- throw new TeiidRuntimeException(RuntimeMetadataPlugin.Util.getString("system_vdb_not_found")); //$NON-NLS-1$
+ VirtualFile mountPoint = VFS.getChild("content/" + CoreConstants.SYSTEM_VDB); //$NON-NLS-1$
+ if (!mountPoint.exists()) {
+ InputStream contents = Module.getCallerModule().getClassLoader().findResourceAsStream(CoreConstants.SYSTEM_VDB, false);
+ if (contents == null) {
+ throw new TeiidRuntimeException(RuntimeMetadataPlugin.Util.getString("system_vdb_not_found")); //$NON-NLS-1$
+ }
+ this.file = VFS.mountZip(contents, CoreConstants.SYSTEM_VDB, mountPoint, TempFileProviderService.provider());
}
+
// uri conversion is only to remove the spaces in URL, note this only with above kind situation
- URI uri = new URI(url.getProtocol(), url.getPath(), null);
- this.vdbRepository.setSystemStore(new IndexMetadataFactory(uri.toURL()).getMetadataStore(null));
+ this.vdbRepository.setSystemStore(new IndexMetadataFactory(mountPoint).getMetadataStore(null));
} catch (URISyntaxException e) {
throw new TeiidRuntimeException(e, RuntimePlugin.Util.getString("system_vdb_load_error")); //$NON-NLS-1$
} catch (IOException e) {
@@ -57,4 +65,13 @@
this.vdbRepository = repo;
}
+ public void stop() {
+ try {
+ if (file != null) {
+ file.close();
+ }
+ } catch (IOException e) {
+ //ignore
+ }
+ }
}
Modified: branches/as7/runtime/src/main/java/org/teiid/deployers/VDBDeployer.java
===================================================================
--- branches/as7/runtime/src/main/java/org/teiid/deployers/VDBDeployer.java 2011-07-13 20:34:20 UTC (rev 3311)
+++ branches/as7/runtime/src/main/java/org/teiid/deployers/VDBDeployer.java 2011-07-14 14:07:35 UTC (rev 3312)
@@ -261,6 +261,9 @@
@Override
public void undeploy(final DeploymentUnit deploymentUnit) {
+ if (!TeiidAttachments.isVDBDeployment(deploymentUnit)) {
+ return;
+ }
VDBMetaData deployment = deploymentUnit.getAttachment(TeiidAttachments.VDB_METADATA);
VirtualFile file = deploymentUnit.getAttachment(Attachments.DEPLOYMENT_ROOT).getRoot();
Modified: branches/as7/test-integration/common/src/test/java/org/teiid/jdbc/TestLocalConnections.java
===================================================================
--- branches/as7/test-integration/common/src/test/java/org/teiid/jdbc/TestLocalConnections.java 2011-07-13 20:34:20 UTC (rev 3311)
+++ branches/as7/test-integration/common/src/test/java/org/teiid/jdbc/TestLocalConnections.java 2011-07-14 14:07:35 UTC (rev 3312)
@@ -22,17 +22,17 @@
package org.teiid.jdbc;
-import static org.junit.Assert.*;
+import static org.junit.Assert.fail;
import java.lang.Thread.UncaughtExceptionHandler;
import java.sql.Connection;
import java.sql.Statement;
import java.util.LinkedHashMap;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
-import org.jboss.netty.handler.timeout.TimeoutException;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
@@ -62,7 +62,7 @@
static Condition waiting = lock.newCondition();
static Condition wait = lock.newCondition();
- public static int blocking() throws InterruptedException {
+ public static int blocking() throws InterruptedException, TimeoutException {
lock.lock();
try {
waiting.signal();
14 years, 5 months
teiid SVN: r3311 - in trunk/engine/src/main/java/org/teiid: query/parser and 1 other directory.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2011-07-13 16:34:20 -0400 (Wed, 13 Jul 2011)
New Revision: 3311
Modified:
trunk/engine/src/main/java/org/teiid/api/exception/query/QueryParserException.java
trunk/engine/src/main/java/org/teiid/query/parser/QueryParser.java
Log:
TEIID-1655 refining parsing error messages
Modified: trunk/engine/src/main/java/org/teiid/api/exception/query/QueryParserException.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/api/exception/query/QueryParserException.java 2011-07-13 19:58:48 UTC (rev 3310)
+++ trunk/engine/src/main/java/org/teiid/api/exception/query/QueryParserException.java 2011-07-13 20:34:20 UTC (rev 3311)
@@ -22,12 +22,16 @@
package org.teiid.api.exception.query;
+import org.teiid.query.parser.ParseException;
+
/**
* Thrown when a query cannot be parsed. This is most likely due to not
* following the Query Parser grammar, which defines how queries are parsed.
*/
public class QueryParserException extends QueryProcessingException {
+
+ private ParseException parseException;
/**
* No-arg constructor required by Externalizable semantics.
@@ -76,4 +80,12 @@
public QueryParserException( Throwable e, String code, String message ) {
super( e, code, message );
}
+
+ public ParseException getParseException() {
+ return parseException;
+ }
+
+ public void setParseException(ParseException parseException) {
+ this.parseException = parseException;
+ }
}
Modified: trunk/engine/src/main/java/org/teiid/query/parser/QueryParser.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/parser/QueryParser.java 2011-07-13 19:58:48 UTC (rev 3310)
+++ trunk/engine/src/main/java/org/teiid/query/parser/QueryParser.java 2011-07-13 20:34:20 UTC (rev 3311)
@@ -23,6 +23,11 @@
package org.teiid.query.parser;
import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.List;
import org.teiid.api.exception.query.QueryParserException;
import org.teiid.query.QueryPlugin;
@@ -186,8 +191,83 @@
}
private QueryParserException convertParserException(ParseException pe) {
- return new QueryParserException(QueryPlugin.Util.getString("QueryParser.parsingError", pe.getMessage())); //$NON-NLS-1$
+ QueryParserException qpe = new QueryParserException(QueryPlugin.Util.getString("QueryParser.parsingError", getMessage(pe, 1, 10))); //$NON-NLS-1$
+ qpe.setParseException(pe);
+ if (pe.currentToken == null) {
+ pe.currentToken = parser.token;
+ }
+ return qpe;
}
+
+ public static String getMessage(ParseException pe, int maxTokenSequence, int maxExpansions) {
+ if (!pe.specialConstructor) {
+ return pe.getMessage();
+ }
+ StringBuffer expected = new StringBuffer();
+ int[][] expectedTokenSequences = pe.expectedTokenSequences;
+ String[] tokenImage = pe.tokenImage;
+ String eol = pe.eol;
+ Token currentToken = pe.currentToken;
+ HashSet<List<Integer>> expansions = new HashSet<List<Integer>>();
+ Arrays.sort(expectedTokenSequences, new Comparator<int[]>() {
+ @Override
+ public int compare(int[] o1, int[] o2) {
+ return o2.length - o1.length;
+ }
+ });
+ int maxSize = expectedTokenSequences[0].length;
+ StringBuilder retval = new StringBuilder("Encountered \""); //$NON-NLS-1$
+ Token tok = currentToken.next;
+ for (int i = 0; i < maxSize; i++) {
+ if (i != 0)
+ retval.append(" "); //$NON-NLS-1$
+ if (tok.kind == 0) {
+ retval.append(tokenImage[0]);
+ break;
+ }
+ retval.append(pe.add_escapes(tok.image));
+ tok = tok.next;
+ }
+ retval.append("\" at line " + currentToken.next.beginLine + ", column " //$NON-NLS-1$ //$NON-NLS-2$
+ + currentToken.next.beginColumn);
+ retval.append("." + eol); //$NON-NLS-1$
+ for (int i = 0; i < expectedTokenSequences.length; i++) {
+ boolean truncateStart = expectedTokenSequences[i].length == maxSize && maxSize > 1 && maxSize > maxTokenSequence;
+ int start = 0;
+ if (truncateStart) {
+ start = expectedTokenSequences[i].length - maxTokenSequence;
+ }
+ List<Integer> expansion = new ArrayList<Integer>(Math.min(maxTokenSequence, expectedTokenSequences[i].length));
+ for (int j = start; j < start+maxTokenSequence; j++) {
+ expansion.add(expectedTokenSequences[i][j]);
+ }
+ if (!expansions.add(expansion) || (!truncateStart && expectedTokenSequences[i][start] == currentToken.next.kind)) {
+ continue;
+ }
+ if (expansions.size() > maxExpansions) {
+ expected.append("...").append(eol).append(" "); //$NON-NLS-1$ //$NON-NLS-2$
+ break;
+ }
+ if (truncateStart) {
+ expected.append("... "); //$NON-NLS-1$
+ }
+ for (int j = start; j < expectedTokenSequences[i].length && j < start+maxTokenSequence; j++) {
+ expected.append(tokenImage[expectedTokenSequences[i][j]])
+ .append(" "); //$NON-NLS-1$
+ }
+ if (expectedTokenSequences[i][Math.min(maxTokenSequence, expectedTokenSequences[i].length - 1)] != 0) {
+ expected.append("..."); //$NON-NLS-1$
+ }
+ expected.append(eol).append(" "); //$NON-NLS-1$
+ }
+ if (expansions.size() == 1) {
+ retval.append("Was expecting:" + eol + " "); //$NON-NLS-1$ //$NON-NLS-2$
+ } else {
+ retval.append("Was expecting one of:" + eol + " "); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ retval.append(expected.toString());
+ return retval.toString();
+ }
/**
* Takes a SQL string representing an SQL expression
14 years, 5 months
teiid SVN: r3310 - in branches/7.4.x: connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/teradata and 4 other directories.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2011-07-13 15:58:48 -0400 (Wed, 13 Jul 2011)
New Revision: 3310
Modified:
branches/7.4.x/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/teradata/TeradataExecutionFactory.java
branches/7.4.x/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/teradata/TestTeradataTranslator.java
branches/7.4.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/FrameUtil.java
branches/7.4.x/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
branches/7.4.x/engine/src/main/resources/org/teiid/query/i18n.properties
branches/7.4.x/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java
Log:
TEIID-1664 removing unnecessary implicit conversions and reverting teradata convert removal
Modified: branches/7.4.x/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/teradata/TeradataExecutionFactory.java
===================================================================
--- branches/7.4.x/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/teradata/TeradataExecutionFactory.java 2011-07-13 16:38:23 UTC (rev 3309)
+++ branches/7.4.x/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/teradata/TeradataExecutionFactory.java 2011-07-13 19:58:48 UTC (rev 3310)
@@ -115,21 +115,12 @@
convert.addNumericBooleanConversions();
registerFunctionModifier(SourceSystemFunctions.CONVERT, convert);
- registerFunctionModifier(SourceSystemFunctions.SUBSTRING, new SubstrModifier(this.convert));
+ registerFunctionModifier(SourceSystemFunctions.SUBSTRING, new AliasModifier("substr")); //$NON-NLS-1$
registerFunctionModifier(SourceSystemFunctions.RAND, new AliasModifier("random")); //$NON-NLS-1$
registerFunctionModifier(SourceSystemFunctions.LOG, new AliasModifier("LN")); //$NON-NLS-1$
- registerFunctionModifier(SourceSystemFunctions.LCASE, new StringOnlyModifier("LOWER", this.convert)); //$NON-NLS-1$
- registerFunctionModifier(SourceSystemFunctions.UCASE, new StringOnlyModifier("UPPER", this.convert)); //$NON-NLS-1$
- registerFunctionModifier(SourceSystemFunctions.LENGTH, new FunctionModifier() {
- @Override
- public List<?> translate(Function function) {
- ArrayList target = new ArrayList();
- target.add("character_length("); //$NON-NLS-1$
- target.addAll(expressionToString(function.getParameters().get(0), convert));
- target.add(")"); //$NON-NLS-1$
- return target;
- }
- });
+ registerFunctionModifier(SourceSystemFunctions.LCASE, new AliasModifier("LOWER")); //$NON-NLS-1$
+ registerFunctionModifier(SourceSystemFunctions.UCASE, new AliasModifier("UPPER")); //$NON-NLS-1$
+ registerFunctionModifier(SourceSystemFunctions.LENGTH, new AliasModifier("character_length")); //$NON-NLS-1$
registerFunctionModifier(SourceSystemFunctions.CURDATE, new AliasModifier("CURRENT_DATE")); //$NON-NLS-1$
registerFunctionModifier(SourceSystemFunctions.CURTIME, new AliasModifier("CURRENT_TIME")); //$NON-NLS-1$
registerFunctionModifier(SourceSystemFunctions.YEAR, new ExtractModifier("YEAR")); //$NON-NLS-1$
@@ -151,9 +142,9 @@
registerFunctionModifier(SourceSystemFunctions.LTRIM, new FunctionModifier() {
@Override
public List<?> translate(Function function) {
- ArrayList target = new ArrayList();
+ ArrayList<Object> target = new ArrayList<Object>();
target.add("TRIM(LEADING FROM ");//$NON-NLS-1$
- target.addAll(expressionToString(function.getParameters().get(0), convert));
+ target.add(function.getParameters().get(0));
target.add(")"); //$NON-NLS-1$
return target;
}
@@ -161,9 +152,9 @@
registerFunctionModifier(SourceSystemFunctions.RTRIM, new FunctionModifier() {
@Override
public List<?> translate(Function function) {
- ArrayList target = new ArrayList();
+ ArrayList<Object> target = new ArrayList<Object>();
target.add("TRIM(TRAILING FROM ");//$NON-NLS-1$
- target.addAll(expressionToString(function.getParameters().get(0), convert));
+ target.add(function.getParameters().get(0));
target.add(")"); //$NON-NLS-1$
return target;
}
@@ -199,7 +190,7 @@
@Override
- public List getSupportedFunctions() {
+ public List<String> getSupportedFunctions() {
List<String> supportedFunctions = new ArrayList<String>();
supportedFunctions.addAll(super.getSupportedFunctions());
@@ -342,67 +333,31 @@
@Override
public List<?> translate(Function function) {
- ArrayList target = new ArrayList();
+ ArrayList<Object> target = new ArrayList<Object>();
Expression expr1 = function.getParameters().get(0);
Expression expr2 = function.getParameters().get(1);
if (function.getParameters().size() > 2) {
Expression expr3 = function.getParameters().get(2);
target.add("position("); //$NON-NLS-1$
- target.addAll(expressionToString(expr1, this.convertModifier));
+ target.add(expr1);
target.add( " in "); //$NON-NLS-1$
target.add("substr("); //$NON-NLS-1$
- target.addAll(expressionToString(expr2, this.convertModifier));
+ target.add(expr2);
target.add(","); //$NON-NLS-1$
target.add(expr3);
target.add("))"); //$NON-NLS-1$
}
else {
target.add("position("); //$NON-NLS-1$
- target.addAll(expressionToString(expr1, this.convertModifier));
+ target.add(expr1);
target.add( " in "); //$NON-NLS-1$
- target.addAll(expressionToString(expr2, this.convertModifier));
+ target.add(expr2);
target.add(")"); //$NON-NLS-1$
}
return target;
}
}
- private static List<?> expressionToString(Expression expr, ConvertModifier modifier) {
- Class tgtType = expr.getType();
- if (tgtType.equals(String.class) && ((expr instanceof Literal) || expr instanceof ColumnReference)) {
- return Arrays.asList(expr);
- }
- else if (tgtType.equals(String.class) && (expr instanceof Function)) {
-
- Function func = (Function)expr;
- while(true) {
- Expression arg1 = func.getParameters().get(0);
- if ((arg1 instanceof Function) && ((Function)arg1).getName().equals("convert")) { //$NON-NLS-1$
- func = (Function)arg1;
- }
- else {
- break;
- }
- }
- Expression arg1 = func.getParameters().get(0);
- if (arg1 instanceof ColumnReference) {
- ColumnReference ref = (ColumnReference)func.getParameters().get(0);
- if(Number.class.isAssignableFrom(ref.getType())) {
- ArrayList target = new ArrayList();
- target.add("cast("); //$NON-NLS-1$
- target.add(func.getParameters().get(0));
- target.add(" AS varchar(100))"); //$NON-NLS-1$
- return target;
- }
- else if (String.class.isAssignableFrom(ref.getType())) {
- return Arrays.asList(ref);
- }
- }
- return modifier.translate(func);
- }
- return Arrays.asList("cast(" , expr, " AS varchar(100))"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
public static class ExtractModifier extends FunctionModifier {
private String type;
public ExtractModifier(String type) {
@@ -425,47 +380,6 @@
}
}
- public static class StringOnlyModifier extends FunctionModifier {
- String funcName;
- ConvertModifier convertModifier;
- public StringOnlyModifier(String name, ConvertModifier converModifier) {
- this.funcName = name;
- this.convertModifier = converModifier;
- }
- @Override
- public List<?> translate(Function function) {
- Expression expr = function.getParameters().get(0);
- ArrayList target = new ArrayList();
- target.add(this.funcName);
- target.add("("); //$NON-NLS-1$
- target.addAll(expressionToString(expr, this.convertModifier));
- target.add(")"); //$NON-NLS-1$
- return target;
- }
- }
-
- public static class SubstrModifier extends FunctionModifier {
- ConvertModifier convertModifier;
- public SubstrModifier(ConvertModifier converModifier) {
- this.convertModifier = converModifier;
- }
- @Override
- public List<?> translate(Function function) {
- Expression expr = function.getParameters().get(0);
- ArrayList target = new ArrayList();
- target.add("substr("); //$NON-NLS-1$
- target.addAll(expressionToString(expr, this.convertModifier));
- target.add(","); //$NON-NLS-1$
- target.add(function.getParameters().get(1));
- if (function.getParameters().size() > 2 ) {
- target.add(","); //$NON-NLS-1$
- target.add(function.getParameters().get(2));
- }
- target.add(")"); //$NON-NLS-1$
- return target;
- }
- }
-
public static class LeftOrRightFunctionModifier extends FunctionModifier {
private LanguageFactory langFactory;
ConvertModifier convertModifier;
@@ -478,11 +392,11 @@
@Override
public List<?> translate(Function function) {
List<Expression> args = function.getParameters();
- ArrayList target = new ArrayList();
+ ArrayList<Object> target = new ArrayList<Object>();
if (function.getName().equalsIgnoreCase("left")) { //$NON-NLS-1$
//substr(string, 1, length)
target.add("substr("); //$NON-NLS-1$
- target.addAll(expressionToString(args.get(0), this.convertModifier));
+ target.add(args.get(0));
target.add(","); //$NON-NLS-1$
target.add(langFactory.createLiteral(Integer.valueOf(1), TypeFacility.RUNTIME_TYPES.INTEGER));
target.add(","); //$NON-NLS-1$
@@ -491,10 +405,10 @@
} else if (function.getName().equalsIgnoreCase("right")) { //$NON-NLS-1$
//substr(case_size, character_length(case_size) -4)
target.add("substr("); //$NON-NLS-1$
- target.addAll(expressionToString(args.get(0), this.convertModifier));
+ target.add(args.get(0));
target.add(",(character_length("); //$NON-NLS-1$
- target.addAll(expressionToString(args.get(0), this.convertModifier));
+ target.add(args.get(0));
target.add(")-"); //$NON-NLS-1$
target.add(args.get(1));
target.add("+1))"); //$NON-NLS-1$ // offset for 1 based index
Modified: branches/7.4.x/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/teradata/TestTeradataTranslator.java
===================================================================
--- branches/7.4.x/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/teradata/TestTeradataTranslator.java 2011-07-13 16:38:23 UTC (rev 3309)
+++ branches/7.4.x/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/teradata/TestTeradataTranslator.java 2011-07-13 19:58:48 UTC (rev 3310)
@@ -84,19 +84,19 @@
@Test public void testIntegerToString() throws Exception {
String input = "SELECT lcase(bigdecimalvalue) FROM BQT1.SMALLA";
- String output = "SELECT LOWER(cast(SmallA.BigDecimalValue AS varchar(100))) FROM SmallA";
+ String output = "SELECT LOWER(cast(SmallA.BigDecimalValue AS varchar(4000))) FROM SmallA";
TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, input, output, TRANSLATOR);
}
@Test public void testSubString() throws Exception {
String input = "SELECT intkey FROM BQT1.SmallA WHERE SUBSTRING(BQT1.SmallA.IntKey, 1) = '1' ORDER BY intkey";
- String output = "SELECT SmallA.IntKey FROM SmallA WHERE substr(cast(SmallA.IntKey AS varchar(100)),1) = '1' ORDER BY 1";
+ String output = "SELECT SmallA.IntKey FROM SmallA WHERE substr(cast(SmallA.IntKey AS varchar(4000)), 1) = '1' ORDER BY 1";
TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, input, output, TRANSLATOR);
}
@Test public void testSubString2() throws Exception {
String input = "SELECT intkey FROM BQT1.SmallA WHERE SUBSTRING(BQT1.SmallA.IntKey, 1, 2) = '1' ORDER BY intkey";
- String output = "SELECT SmallA.IntKey FROM SmallA WHERE substr(cast(SmallA.IntKey AS varchar(100)),1,2) = '1' ORDER BY 1";
+ String output = "SELECT SmallA.IntKey FROM SmallA WHERE substr(cast(SmallA.IntKey AS varchar(4000)), 1, 2) = '1' ORDER BY 1";
TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, input, output, TRANSLATOR);
}
@@ -108,7 +108,7 @@
@Test public void testLocate() throws Exception {
String input = "SELECT INTKEY, BIGDECIMALVALUE FROM BQT1.SmallA WHERE LOCATE('-', BIGDECIMALVALUE) = 1 ORDER BY intkey";
- String output = "SELECT SmallA.IntKey, SmallA.BigDecimalValue FROM SmallA WHERE position('-' in cast(SmallA.BigDecimalValue AS varchar(100))) = 1 ORDER BY 1";
+ String output = "SELECT SmallA.IntKey, SmallA.BigDecimalValue FROM SmallA WHERE position('-' in cast(SmallA.BigDecimalValue AS varchar(4000))) = 1 ORDER BY 1";
TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, input, output, TRANSLATOR);
}
@@ -222,13 +222,13 @@
@Test public void testRightFunction() throws Exception {
String input = "SELECT INTKEY, FLOATNUM FROM BQT1.SmallA WHERE right(FLOATNUM, 2) <> 0 ORDER BY INTKEY";
- String out = "SELECT SmallA.IntKey, SmallA.FloatNum FROM SmallA WHERE substr(cast(SmallA.FloatNum AS varchar(100)),(character_length(cast(SmallA.FloatNum AS varchar(100)))-2+1)) <> '0' ORDER BY 1";
+ String out = "SELECT SmallA.IntKey, SmallA.FloatNum FROM SmallA WHERE substr(cast(SmallA.FloatNum AS varchar(4000)),(character_length(cast(SmallA.FloatNum AS varchar(4000)))-2+1)) <> '0' ORDER BY 1";
TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, null, input, out, TRANSLATOR);
}
@Test public void testLocateFunction() throws Exception {
String input = "SELECT INTKEY, STRINGKEY, SHORTVALUE FROM BQT1.SmallA WHERE (LOCATE(0, STRINGKEY) = 2) OR (LOCATE(2, SHORTVALUE, 4) = 6) ORDER BY intkey";
- String out = "SELECT SmallA.IntKey, SmallA.StringKey, SmallA.ShortValue FROM SmallA WHERE position('0' in SmallA.StringKey) = 2 OR position('2' in substr(cast(SmallA.ShortValue AS varchar(100)),4)) = 6 ORDER BY 1";
+ String out = "SELECT SmallA.IntKey, SmallA.StringKey, SmallA.ShortValue FROM SmallA WHERE position('0' in SmallA.StringKey) = 2 OR position('2' in substr(cast(SmallA.ShortValue AS varchar(4000)),4)) = 6 ORDER BY 1";
TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, null, input, out, TRANSLATOR);
}
}
Modified: branches/7.4.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/FrameUtil.java
===================================================================
--- branches/7.4.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/FrameUtil.java 2011-07-13 16:38:23 UTC (rev 3309)
+++ branches/7.4.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/FrameUtil.java 2011-07-13 19:58:48 UTC (rev 3310)
@@ -37,7 +37,6 @@
import org.teiid.api.exception.query.QueryPlannerException;
import org.teiid.core.TeiidComponentException;
import org.teiid.core.TeiidProcessingException;
-import org.teiid.core.TeiidRuntimeException;
import org.teiid.core.util.Assertion;
import org.teiid.query.QueryPlugin;
import org.teiid.query.metadata.QueryMetadataInterface;
@@ -49,17 +48,21 @@
import org.teiid.query.resolver.util.AccessPattern;
import org.teiid.query.resolver.util.ResolverUtil;
import org.teiid.query.rewriter.QueryRewriter;
+import org.teiid.query.sql.LanguageObject;
import org.teiid.query.sql.lang.Command;
import org.teiid.query.sql.lang.CompoundCriteria;
import org.teiid.query.sql.lang.Criteria;
import org.teiid.query.sql.lang.GroupBy;
import org.teiid.query.sql.lang.OrderBy;
+import org.teiid.query.sql.lang.OrderByItem;
import org.teiid.query.sql.lang.QueryCommand;
import org.teiid.query.sql.lang.Select;
import org.teiid.query.sql.lang.StoredProcedure;
+import org.teiid.query.sql.symbol.AliasSymbol;
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.SingleElementSymbol;
import org.teiid.query.sql.util.SymbolMap;
@@ -124,15 +127,15 @@
}
static boolean canConvertAccessPatterns(PlanNode sourceNode) {
- List accessPatterns = (List)sourceNode.getProperty(NodeConstants.Info.ACCESS_PATTERNS);
+ List<AccessPattern> accessPatterns = (List)sourceNode.getProperty(NodeConstants.Info.ACCESS_PATTERNS);
if (accessPatterns == null) {
return true;
}
SymbolMap symbolMap = (SymbolMap)sourceNode.getProperty(NodeConstants.Info.SYMBOL_MAP);
- for (Iterator i = accessPatterns.iterator(); i.hasNext();) {
- AccessPattern ap = (AccessPattern)i.next();
- for (Iterator elems = ap.getUnsatisfied().iterator(); elems.hasNext();) {
- ElementSymbol symbol = (ElementSymbol)elems.next();
+ for (Iterator<AccessPattern> i = accessPatterns.iterator(); i.hasNext();) {
+ AccessPattern ap = i.next();
+ for (Iterator<ElementSymbol> elems = ap.getUnsatisfied().iterator(); elems.hasNext();) {
+ ElementSymbol symbol = elems.next();
Expression mapped = convertExpression(symbol, symbolMap.asMap());
if (ElementCollectorVisitor.getElements(mapped, true).isEmpty()) {
return false;
@@ -153,15 +156,15 @@
if (accessPatterns != null) {
for (AccessPattern ap : accessPatterns) {
Set<ElementSymbol> newElements = new HashSet<ElementSymbol>();
- for (Iterator elems = ap.getUnsatisfied().iterator(); elems.hasNext();) {
- ElementSymbol symbol = (ElementSymbol)elems.next();
+ for (Iterator<ElementSymbol> elems = ap.getUnsatisfied().iterator(); elems.hasNext();) {
+ ElementSymbol symbol = elems.next();
Expression mapped = convertExpression(symbol, symbolMap);
newElements.addAll(ElementCollectorVisitor.getElements(mapped, true));
}
ap.setUnsatisfied(newElements);
Set<ElementSymbol> newHistory = new HashSet<ElementSymbol>();
- for (Iterator elems = ap.getCurrentElements().iterator(); elems.hasNext();) {
- ElementSymbol symbol = (ElementSymbol)elems.next();
+ for (Iterator<ElementSymbol> elems = ap.getCurrentElements().iterator(); elems.hasNext();) {
+ ElementSymbol symbol = elems.next();
Expression mapped = convertExpression(symbol, symbolMap);
newHistory.addAll(ElementCollectorVisitor.getElements(mapped, true));
}
@@ -228,6 +231,11 @@
List<SingleElementSymbol> projectedSymbols = (List<SingleElementSymbol>)node.getProperty(NodeConstants.Info.PROJECT_COLS);
Select select = new Select(projectedSymbols);
ExpressionMappingVisitor.mapExpressions(select, symbolMap);
+ if (rewrite) {
+ for (LanguageObject expr : select.getSymbols()) {
+ rewriteSingleElementSymbol(metadata, (SingleElementSymbol) expr);
+ }
+ }
node.setProperty(NodeConstants.Info.PROJECT_COLS, select.getSymbols());
if (!singleMapping) {
GroupsUsedByElementsVisitor.getGroups(select, groups);
@@ -252,6 +260,11 @@
} else if(type == NodeConstants.Types.SORT) {
OrderBy orderBy = (OrderBy)node.getProperty(NodeConstants.Info.SORT_ORDER);
ExpressionMappingVisitor.mapExpressions(orderBy, symbolMap);
+ if (rewrite) {
+ for (OrderByItem item : orderBy.getOrderByItems()) {
+ rewriteSingleElementSymbol(metadata, item.getSymbol());
+ }
+ }
if (!singleMapping) {
GroupsUsedByElementsVisitor.getGroups(orderBy, groups);
}
@@ -269,6 +282,25 @@
convertAccessPatterns(symbolMap, node);
}
}
+
+ private static void rewriteSingleElementSymbol(
+ QueryMetadataInterface metadata, SingleElementSymbol ses) throws QueryPlannerException {
+ try {
+ if (ses instanceof AliasSymbol) {
+ ses = ((AliasSymbol)ses).getSymbol();
+ }
+ if (ses instanceof ExpressionSymbol) {
+ ExpressionSymbol es = (ExpressionSymbol)ses;
+ if (es.getExpression() != null) {
+ es.setExpression(QueryRewriter.rewriteExpression(es.getExpression(), null, null, metadata));
+ }
+ }
+ } catch(TeiidProcessingException e) {
+ throw new QueryPlannerException(e, QueryPlugin.Util.getString("ERR.015.004.0023", ses)); //$NON-NLS-1$
+ } catch (TeiidComponentException e) {
+ throw new QueryPlannerException(e, QueryPlugin.Util.getString("ERR.015.004.0023", ses)); //$NON-NLS-1$
+ }
+ }
private static Expression convertExpression(Expression expression, Map symbolMap) {
@@ -303,7 +335,7 @@
} catch(TeiidProcessingException e) {
throw new QueryPlannerException(e, QueryPlugin.Util.getString("ERR.015.004.0023", criteria)); //$NON-NLS-1$
} catch (TeiidComponentException e) {
- throw new TeiidRuntimeException(e);
+ throw new QueryPlannerException(e, QueryPlugin.Util.getString("ERR.015.004.0023", criteria)); //$NON-NLS-1$
}
}
Modified: branches/7.4.x/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
===================================================================
--- branches/7.4.x/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java 2011-07-13 16:38:23 UTC (rev 3309)
+++ branches/7.4.x/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java 2011-07-13 19:58:48 UTC (rev 3310)
@@ -52,6 +52,7 @@
import org.teiid.core.TeiidProcessingException;
import org.teiid.core.TeiidRuntimeException;
import org.teiid.core.types.DataTypeManager;
+import org.teiid.core.types.Transform;
import org.teiid.core.util.Assertion;
import org.teiid.core.util.TimestampWithTimezone;
import org.teiid.language.SQLConstants.NonReserved;
@@ -876,11 +877,11 @@
try {
PostOrderNavigator.doVisit(obj, visitor);
} catch (TeiidRuntimeException err) {
- if (err.getChild() instanceof TeiidComponentException) {
- throw (TeiidComponentException)err.getChild();
+ if (err.getCause() instanceof TeiidComponentException) {
+ throw (TeiidComponentException)err.getCause();
}
- if (err.getChild() instanceof TeiidProcessingException) {
- throw (TeiidProcessingException)err.getChild();
+ if (err.getCause() instanceof TeiidProcessingException) {
+ throw (TeiidProcessingException)err.getCause();
}
throw err;
}
@@ -2514,17 +2515,44 @@
}
function.setArgs(newArgs);
- if( FunctionLibrary.isConvert(function) &&
- newArgs[1] instanceof Constant) {
-
- Class srcType = newArgs[0].getType();
- String tgtTypeName = (String) ((Constant)newArgs[1]).getValue();
- Class tgtType = DataTypeManager.getDataTypeClass(tgtTypeName);
+ if( FunctionLibrary.isConvert(function)) {
+ Class<?> srcType = newArgs[0].getType();
+ Class<?> tgtType = function.getType();
if(srcType != null && tgtType != null && srcType.equals(tgtType)) {
- return newArgs[0];
+ return newArgs[0]; //unnecessary conversion
}
-
+
+ if (!(newArgs[0] instanceof Function) || tgtType == DataTypeManager.DefaultDataClasses.OBJECT) {
+ return function;
+ }
+ Function nested = (Function) newArgs[0];
+ if (!FunctionLibrary.isConvert(nested)) {
+ return function;
+ }
+ Class<?> nestedType = nested.getArgs()[0].getType();
+
+ Transform t = DataTypeManager.getTransform(nestedType, nested.getType());
+ if (t.isExplicit()) {
+ //explicit conversions are required
+ return function;
+ }
+ if (DataTypeManager.getTransform(nestedType, tgtType) == null) {
+ //no direct conversion exists
+ return function;
+ }
+ //can't remove a convert that would alter the lexical form
+ if (tgtType == DataTypeManager.DefaultDataClasses.STRING &&
+ (nestedType == DataTypeManager.DefaultDataClasses.BOOLEAN
+ || nestedType == DataTypeManager.DefaultDataClasses.DATE
+ || nestedType == DataTypeManager.DefaultDataClasses.TIME
+ || tgtType == DataTypeManager.DefaultDataClasses.BIG_DECIMAL
+ || tgtType == DataTypeManager.DefaultDataClasses.FLOAT
+ || (tgtType == DataTypeManager.DefaultDataClasses.DOUBLE && srcType != DataTypeManager.DefaultDataClasses.FLOAT))) {
+ return function;
+ }
+ //nested implicit transform is not needed
+ return rewriteExpressionDirect(ResolverUtil.getConversion(nested.getArgs()[0], DataTypeManager.getDataTypeName(nestedType), DataTypeManager.getDataTypeName(tgtType), false, funcLibrary));
}
//convert DECODESTRING function to CASE expression
Modified: branches/7.4.x/engine/src/main/resources/org/teiid/query/i18n.properties
===================================================================
--- branches/7.4.x/engine/src/main/resources/org/teiid/query/i18n.properties 2011-07-13 16:38:23 UTC (rev 3309)
+++ branches/7.4.x/engine/src/main/resources/org/teiid/query/i18n.properties 2011-07-13 19:58:48 UTC (rev 3310)
@@ -232,7 +232,7 @@
ERR.015.004.0010= Unknown group specified in OPTION MAKEDEP/MAKENOTDEP: {0}
ERR.015.004.0012= Group has an access pattern which has not been met: group(s) {0}; access pattern(s) {1}
ERR.015.004.0020= Error getting model for {0}
-ERR.015.004.0023= Error rewriting criteria: {0}
+ERR.015.004.0023= Error rewriting: {0}
ERR.015.004.0024= Unable to create a query plan that sends a criteria to \"{0}\". This connection factory requires criteria set to true indicating that a query against this model requires criteria.
ERR.015.004.0029= Could not resolve group symbol {0}
ERR.015.004.0035= The criteria {0} has elements from the root staging table and the document nodes which is not allowed.
Modified: branches/7.4.x/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java
===================================================================
--- branches/7.4.x/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java 2011-07-13 16:38:23 UTC (rev 3309)
+++ branches/7.4.x/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java 2011-07-13 19:58:48 UTC (rev 3310)
@@ -124,11 +124,11 @@
}
private Map<ElementSymbol, Integer> elements;
- private List<List> tuples;
+ private List<List<? extends Object>> tuples;
@Before public void setUp() {
elements = null;
- tuples = new ArrayList<List>();
+ tuples = new ArrayList<List<? extends Object>>();
}
private Criteria helpTestRewriteCriteria(String original, Criteria expectedCrit, QueryMetadataInterface metadata) {
@@ -138,7 +138,7 @@
// rewrite
try {
ArrayList<Boolean> booleanVals = new ArrayList<Boolean>(tuples.size());
- for (List<Object> tuple : tuples) {
+ for (List<?> tuple : tuples) {
booleanVals.add(new Evaluator(elements, null, null).evaluate(origCrit, tuple));
}
actual = QueryRewriter.rewriteCriteria(origCrit, null, null, metadata);
@@ -2448,5 +2448,16 @@
String sql = "parsedate_(pm1.g1.e1) = {d'2001-01-01'}";
helpTestRewriteCriteria(sql, parseCriteria(sql, metadata), metadata);
}
+
+ @Test public void testRewriteNestedConvert() throws Exception {
+ helpTestRewriteExpression("cast(cast(pm1.g1.e3 as integer) as long)", "cast(pm1.g1.e3 as long)", RealMetadataFactory.example1Cached()); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ @Test public void testRewriteNestedConvert1() throws Exception {
+ helpTestRewriteExpression("cast(cast(pm1.g1.e3 as integer) as string)", "convert(convert(pm1.g1.e3, integer), string)", RealMetadataFactory.example1Cached()); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ @Test public void testRewriteNestedConvert2() throws Exception {
+ helpTestRewriteExpression("cast(cast(pm1.g1.e3 as string) as clob)", "convert(convert(pm1.g1.e3, string), clob)", RealMetadataFactory.example1Cached()); //$NON-NLS-1$ //$NON-NLS-2$
+ }
}
14 years, 5 months
teiid SVN: r3309 - in branches/7.1.1.CP3: build/kits/jboss-container/deploy/teiid and 1 other directories.
by teiid-commits@lists.jboss.org
Author: rareddy
Date: 2011-07-13 12:38:23 -0400 (Wed, 13 Jul 2011)
New Revision: 3309
Modified:
branches/7.1.1.CP3/build/kits/jboss-container/deploy/teiid/teiid-cache-manager-jboss-beans-rename-me.xml
branches/7.1.1.CP3/cache-jbosscache/src/main/java/org/teiid/cache/jboss/JBossCacheFactory.java
branches/7.1.1.CP3/pom.xml
Log:
TEIID-1493: When a node rejoins the cluster after the initial cache has been populated, during the join time the state has been set to not transfer. This need be set to transfer, also JBoss cache only transfers the state on "active" regions.
Modified: branches/7.1.1.CP3/build/kits/jboss-container/deploy/teiid/teiid-cache-manager-jboss-beans-rename-me.xml
===================================================================
--- branches/7.1.1.CP3/build/kits/jboss-container/deploy/teiid/teiid-cache-manager-jboss-beans-rename-me.xml 2011-07-13 16:34:27 UTC (rev 3308)
+++ branches/7.1.1.CP3/build/kits/jboss-container/deploy/teiid/teiid-cache-manager-jboss-beans-rename-me.xml 2011-07-13 16:38:23 UTC (rev 3309)
@@ -85,7 +85,7 @@
<!-- Hibernate 2LC can replicate custom types, so we use marshalling -->
<property name="useRegionBasedMarshalling">true</property>
<!-- Must match the value of "useRegionBasedMarshalling" -->
- <property name="inactiveOnStartup">true</property>
+ <property name="inactiveOnStartup">false</property>
<!-- Disable asynchronous RPC marshalling/sending -->
<property name="serializationExecutorPoolSize">0</property>
Modified: branches/7.1.1.CP3/cache-jbosscache/src/main/java/org/teiid/cache/jboss/JBossCacheFactory.java
===================================================================
--- branches/7.1.1.CP3/cache-jbosscache/src/main/java/org/teiid/cache/jboss/JBossCacheFactory.java 2011-07-13 16:34:27 UTC (rev 3308)
+++ branches/7.1.1.CP3/cache-jbosscache/src/main/java/org/teiid/cache/jboss/JBossCacheFactory.java 2011-07-13 16:38:23 UTC (rev 3309)
@@ -59,6 +59,7 @@
if (!this.cacheStore.getCacheStatus().allowInvocations()) {
this.cacheStore.start();
+ this.cacheStore.getRegion(this.cacheStore.getRoot().getFqn(), true).activate();
}
Node cacheRoot = this.cacheStore.getRoot().addChild(Fqn.fromString("Teiid")); //$NON-NLS-1$
@@ -67,6 +68,7 @@
Region cacheRegion = this.cacheStore.getRegion(node.getFqn(), true);
cacheRegion.setEvictionRegionConfig(buildEvictionConfig(node.getFqn(), config));
+ cacheRegion.activate();
JBossCache jc = null;
if (config != null && config.getPolicy().equals(Policy.EXPIRATION)) {
Modified: branches/7.1.1.CP3/pom.xml
===================================================================
--- branches/7.1.1.CP3/pom.xml 2011-07-13 16:34:27 UTC (rev 3308)
+++ branches/7.1.1.CP3/pom.xml 2011-07-13 16:38:23 UTC (rev 3309)
@@ -365,7 +365,7 @@
<dependency>
<groupId>org.jboss.cache</groupId>
<artifactId>jbosscache-core</artifactId>
- <version>3.1.0.GA</version>
+ <version>3.2.5.GA</version>
<exclusions>
<exclusion>
<groupId>javax.transaction</groupId>
14 years, 5 months
teiid SVN: r3308 - in branches/7.4.x: test-integration/common/src/test/java/org/teiid/jdbc and 1 other directory.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2011-07-13 12:34:27 -0400 (Wed, 13 Jul 2011)
New Revision: 3308
Modified:
branches/7.4.x/engine/src/main/java/org/teiid/dqp/internal/process/RequestWorkItem.java
branches/7.4.x/test-integration/common/src/test/java/org/teiid/jdbc/TestLocalConnections.java
Log:
TEIID-1614 refining fix for possible hangs in embedded execution
Modified: branches/7.4.x/engine/src/main/java/org/teiid/dqp/internal/process/RequestWorkItem.java
===================================================================
--- branches/7.4.x/engine/src/main/java/org/teiid/dqp/internal/process/RequestWorkItem.java 2011-07-12 19:23:10 UTC (rev 3307)
+++ branches/7.4.x/engine/src/main/java/org/teiid/dqp/internal/process/RequestWorkItem.java 2011-07-13 16:34:27 UTC (rev 3308)
@@ -163,6 +163,7 @@
private long processingTimestamp = System.currentTimeMillis();
protected boolean useCallingThread;
+ private volatile boolean hasThread;
public RequestWorkItem(DQPCore dqpCore, RequestMessage requestMsg, Request request, ResultsReceiver<ResultsMessage> receiver, RequestID requestID, DQPWorkContext workContext) {
this.requestMsg = requestMsg;
@@ -200,26 +201,34 @@
@Override
public void run() {
- while (!isDoneProcessing()) {
- super.run();
- if (!useCallingThread) {
- break;
- }
- //should use the calling thread
- synchronized (this) {
- if (this.resultsReceiver == null) {
- break; //allow results to be processed by calling thread
+ hasThread = true;
+ try {
+ while (!isDoneProcessing()) {
+ super.run();
+ if (!useCallingThread) {
+ break;
}
- try {
- wait();
- } catch (InterruptedException e) {
+ //should use the calling thread
+ synchronized (this) {
+ if (this.resultsReceiver == null) {
+ break; //allow results to be processed by calling thread
+ }
+ if (this.getThreadState() == ThreadState.MORE_WORK) {
+ continue;
+ }
try {
- requestCancel();
- } catch (TeiidComponentException e1) {
- throw new TeiidRuntimeException(e1);
+ wait();
+ } catch (InterruptedException e) {
+ try {
+ requestCancel();
+ } catch (TeiidComponentException e1) {
+ throw new TeiidRuntimeException(e1);
+ }
}
}
}
+ } finally {
+ hasThread = false;
}
}
@@ -237,14 +246,15 @@
public void doMoreWork() {
boolean run = false;
synchronized (this) {
- run = this.getThreadState() == ThreadState.IDLE;
moreWork();
if (!useCallingThread || this.getThreadState() != ThreadState.MORE_WORK) {
return;
}
+ run = !hasThread;
}
if (run) {
//run outside of the lock
+ LogManager.logDetail(LogConstants.CTX_DQP, "Restarting processing using the calling thread", requestID); //$NON-NLS-1$
run();
}
}
Modified: branches/7.4.x/test-integration/common/src/test/java/org/teiid/jdbc/TestLocalConnections.java
===================================================================
--- branches/7.4.x/test-integration/common/src/test/java/org/teiid/jdbc/TestLocalConnections.java 2011-07-12 19:23:10 UTC (rev 3307)
+++ branches/7.4.x/test-integration/common/src/test/java/org/teiid/jdbc/TestLocalConnections.java 2011-07-13 16:34:27 UTC (rev 3308)
@@ -26,17 +26,20 @@
import java.lang.Thread.UncaughtExceptionHandler;
import java.sql.Connection;
+import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
+import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
-import org.jboss.netty.handler.timeout.TimeoutException;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
@@ -74,12 +77,14 @@
static Condition waiting = lock.newCondition();
static Condition wait = lock.newCondition();
+ static Semaphore sourceCounter = new Semaphore(0);
+
public static int blocking() throws InterruptedException {
lock.lock();
try {
waiting.signal();
if (!wait.await(2, TimeUnit.SECONDS)) {
- throw new TimeoutException();
+ throw new RuntimeException();
}
} finally {
lock.unlock();
@@ -88,7 +93,7 @@
}
static FakeServer server = new FakeServer();
-
+
@SuppressWarnings("serial")
@BeforeClass public static void oneTimeSetup() throws Exception {
server.setUseCallingThread(true);
@@ -106,13 +111,15 @@
throws TranslatorException {
return new ResultSetExecution() {
+ boolean returnedRow = false;
+
@Override
public void execute() throws TranslatorException {
lock.lock();
try {
- waiting.signal();
+ sourceCounter.release();
if (!wait.await(2, TimeUnit.SECONDS)) {
- throw new TimeoutException();
+ throw new RuntimeException();
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
@@ -133,8 +140,11 @@
@Override
public List<?> next() throws TranslatorException, DataNotAvailableException {
- // TODO Auto-generated method stub
- return null;
+ if (returnedRow) {
+ return null;
+ }
+ returnedRow = true;
+ return new ArrayList<Object>(Collections.singleton(null));
}
};
}
@@ -255,23 +265,68 @@
SimpleUncaughtExceptionHandler handler = new SimpleUncaughtExceptionHandler();
t.setUncaughtExceptionHandler(handler);
+ sourceCounter.acquire();
+
+ //t should now be waiting also
+
lock.lock();
try {
- assertTrue(waiting.await(2, TimeUnit.SECONDS));
+ wait.signal();
} finally {
lock.unlock();
- }
+ }
+
+ //t should finish
+ t.join();
+ if (handler.t != null) {
+ throw handler.t;
+ }
+ }
+
+ @Test public void testWaitMultiple() throws Throwable {
+ final Connection c = server.createConnection("jdbc:teiid:test");
+
+ Thread t = new Thread() {
+ public void run() {
+ Statement s;
+ try {
+ s = c.createStatement();
+ assertTrue(s.execute("select part_id from parts union all select part_id from parts"));
+ ResultSet r = s.getResultSet();
+
+ //wake up the other source thread, should put the requestworkitem into the more work state
+ lock.lock();
+ try {
+ wait.signal();
+ } finally {
+ lock.unlock();
+ }
+ Thread.sleep(1000); //TODO: need a better hook to determine that connector work has finished
+ while (r.next()) {
+ //will hang unless this thread is allowed to resume processing
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ };
+ t.start();
+ SimpleUncaughtExceptionHandler handler = new SimpleUncaughtExceptionHandler();
+ t.setUncaughtExceptionHandler(handler);
+
+ sourceCounter.acquire(2);
+
//t should now be waiting also
+ //wake up 1 source thread
lock.lock();
try {
wait.signal();
} finally {
lock.unlock();
}
-
- //t should finish
+
t.join();
if (handler.t != null) {
14 years, 5 months