[teiid-commits] teiid SVN: r2973 - in trunk: engine/src/main/java/org/teiid/query/optimizer/relational and 13 other directories.
teiid-commits at lists.jboss.org
teiid-commits at lists.jboss.org
Mon Mar 7 16:03:53 EST 2011
Author: shawkins
Date: 2011-03-07 16:03:52 -0500 (Mon, 07 Mar 2011)
New Revision: 2973
Modified:
trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/LanguageBridgeFactory.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/CriteriaCapabilityValidatorVisitor.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/RuleMergeCriteria.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleRemoveOptionalJoins.java
trunk/engine/src/main/java/org/teiid/query/processor/relational/LimitNode.java
trunk/engine/src/main/java/org/teiid/query/processor/relational/RelationalNodeUtil.java
trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
trunk/engine/src/main/java/org/teiid/query/sql/lang/Limit.java
trunk/engine/src/test/java/org/teiid/query/optimizer/TestOptimizer.java
trunk/engine/src/test/java/org/teiid/query/optimizer/TestSubqueryPushdown.java
trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java
trunk/engine/src/test/java/org/teiid/query/processor/proc/TestProcedureProcessor.java
trunk/engine/src/test/java/org/teiid/query/processor/relational/TestAccessNode.java
trunk/engine/src/test/java/org/teiid/query/rewriter/TestOrderByRewrite.java
trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java
trunk/engine/src/test/java/org/teiid/query/sql/lang/TestLimit.java
trunk/test-integration/common/src/test/java/org/teiid/connector/language/TestLanguageUtil.java
trunk/test-integration/common/src/test/java/org/teiid/dqp/internal/process/TestTPCR.java
Log:
TEIID-1496 TEIID-1497 adding or rewrite and implicit limit handling for exists/scalar subqueries
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-03-07 19:20:20 UTC (rev 2972)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/LanguageBridgeFactory.java 2011-03-07 21:03:52 UTC (rev 2973)
@@ -350,7 +350,7 @@
}
Exists translate(ExistsCriteria criteria) {
- return new Exists(translate((QueryCommand)criteria.getCommand()));
+ return new Exists(translate(criteria.getCommand()));
}
IsNull translate(IsNullCriteria criteria) {
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-03-07 19:20:20 UTC (rev 2972)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/PlanToProcessConverter.java 2011-03-07 21:03:52 UTC (rev 2973)
@@ -450,7 +450,9 @@
case NodeConstants.Types.TUPLE_LIMIT:
Expression rowLimit = (Expression)node.getProperty(NodeConstants.Info.MAX_TUPLE_LIMIT);
Expression offset = (Expression)node.getProperty(NodeConstants.Info.OFFSET_TUPLE_COUNT);
- processNode = new LimitNode(getID(), rowLimit, offset);
+ LimitNode ln = new LimitNode(getID(), rowLimit, offset);
+ ln.setImplicit(node.hasBooleanProperty(Info.IS_IMPLICIT_LIMIT));
+ processNode = ln;
break;
case NodeConstants.Types.NULL:
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-03-07 19:20:20 UTC (rev 2972)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java 2011-03-07 21:03:52 UTC (rev 2973)
@@ -638,7 +638,7 @@
subqueryContainer.getCommand().setProcessorPlan(plan);
if (c == null) {
- RuleCollapseSource.replaceCorrelatedReferences(subqueryContainer);
+ RuleCollapseSource.prepareSubquery(subqueryContainer);
}
}
return false;
@@ -1014,6 +1014,9 @@
attach = true;
}
if (attach) {
+ if (limit.isImplicit()) {
+ limitNode.setProperty(Info.IS_IMPLICIT_LIMIT, true);
+ }
attachLast(limitNode, plan);
plan = limitNode;
}
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-03-07 19:20:20 UTC (rev 2972)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/plantree/NodeConstants.java 2011-03-07 21:03:52 UTC (rev 2973)
@@ -144,6 +144,7 @@
// Tuple limit and offset
MAX_TUPLE_LIMIT, // Expression that evaluates to the max number of tuples generated
OFFSET_TUPLE_COUNT, // Expression that evaluates to the tuple offset of the starting tuple
+ IS_IMPLICIT_LIMIT, // Boolean if the limit is created by the rewriter as part of a subquery optimization
// Common AP Information
ACCESS_PATTERNS, // Collection <List <Object element ID> >
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/CriteriaCapabilityValidatorVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/CriteriaCapabilityValidatorVisitor.java 2011-03-07 19:20:20 UTC (rev 2972)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/CriteriaCapabilityValidatorVisitor.java 2011-03-07 21:03:52 UTC (rev 2973)
@@ -37,6 +37,7 @@
import org.teiid.query.optimizer.capabilities.SourceCapabilities.Capability;
import org.teiid.query.processor.ProcessorPlan;
import org.teiid.query.processor.relational.AccessNode;
+import org.teiid.query.processor.relational.LimitNode;
import org.teiid.query.processor.relational.RelationalNode;
import org.teiid.query.processor.relational.RelationalPlan;
import org.teiid.query.sql.LanguageObject;
@@ -529,10 +530,19 @@
// Check that the plan is just an access node
RelationalNode accessNode = rplan.getRootNode();
- if(accessNode == null || ! (accessNode instanceof AccessNode) || accessNode.getChildren()[0] != null) {
- return null;
+
+ if (accessNode instanceof LimitNode) {
+ LimitNode ln = (LimitNode)accessNode;
+ if (!ln.isImplicit()) {
+ return null;
+ }
+ accessNode = ln.getChildren()[0];
}
+ if (! (accessNode instanceof AccessNode) || accessNode.getChildren()[0] != null) {
+ return null;
+ }
+
// Check that command in access node is a query
Command command = ((AccessNode)accessNode).getCommand();
if(command == null || !(command instanceof QueryCommand) || ((command instanceof Query) && ((Query)command).getIsXML())) {
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-03-07 19:20:20 UTC (rev 2972)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleCollapseSource.java 2011-03-07 21:03:52 UTC (rev 2973)
@@ -45,13 +45,13 @@
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.processor.relational.AccessNode;
import org.teiid.query.processor.relational.RelationalPlan;
import org.teiid.query.resolver.util.ResolverUtil;
import org.teiid.query.rewriter.QueryRewriter;
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.ExistsCriteria;
import org.teiid.query.sql.lang.From;
import org.teiid.query.sql.lang.FromClause;
import org.teiid.query.sql.lang.GroupBy;
@@ -75,6 +75,7 @@
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.ScalarSubquery;
import org.teiid.query.sql.symbol.SingleElementSymbol;
import org.teiid.query.sql.util.SymbolMap;
import org.teiid.query.sql.visitor.ExpressionMappingVisitor;
@@ -228,7 +229,7 @@
Query query = new Query();
Select select = new Select();
List<SingleElementSymbol> columns = (List<SingleElementSymbol>)node.getProperty(NodeConstants.Info.OUTPUT_COLS);
- replaceCorrelatedReferences(ValueIteratorProviderCollectorVisitor.getValueIteratorProviders(columns));
+ prepareSubqueries(ValueIteratorProviderCollectorVisitor.getValueIteratorProviders(columns));
select.addSymbols(columns);
query.setSelect(select);
query.setFrom(new From());
@@ -284,7 +285,7 @@
switch(node.getType()) {
case NodeConstants.Types.JOIN:
{
- replaceCorrelatedReferences(node.getSubqueryContainers());
+ prepareSubqueries(node.getSubqueryContainers());
JoinType joinType = (JoinType) node.getProperty(NodeConstants.Info.JOIN_TYPE);
List<Criteria> crits = (List<Criteria>) node.getProperty(NodeConstants.Info.JOIN_CRITERIA);
@@ -362,7 +363,7 @@
case NodeConstants.Types.SELECT:
{
Criteria crit = (Criteria) node.getProperty(NodeConstants.Info.SELECT_CRITERIA);
- replaceCorrelatedReferences(node.getSubqueryContainers());
+ prepareSubqueries(node.getSubqueryContainers());
if(!node.hasBooleanProperty(NodeConstants.Info.IS_HAVING)) {
query.setCriteria( CompoundCriteria.combineCriteria(query.getCriteria(), crit) );
} else {
@@ -396,25 +397,33 @@
}
}
- private void replaceCorrelatedReferences(List<SubqueryContainer> containers) {
+ private void prepareSubqueries(List<SubqueryContainer> containers) {
for (SubqueryContainer container : containers) {
- replaceCorrelatedReferences(container);
+ prepareSubquery(container);
}
}
- public static void replaceCorrelatedReferences(SubqueryContainer container) {
+ public static void prepareSubquery(SubqueryContainer container) {
RelationalPlan subqueryPlan = (RelationalPlan)container.getCommand().getProcessorPlan();
- if (subqueryPlan == null || !(subqueryPlan.getRootNode() instanceof AccessNode)) {
+ QueryCommand command = CriteriaCapabilityValidatorVisitor.getQueryCommand(subqueryPlan);
+ if (command == null) {
return;
}
- AccessNode child = (AccessNode)subqueryPlan.getRootNode();
- Command command = child.getCommand();
final SymbolMap map = container.getCommand().getCorrelatedReferences();
if (map != null) {
ExpressionMappingVisitor visitor = new RuleMergeCriteria.ReferenceReplacementVisitor(map);
DeepPostOrderNavigator.doVisit(command, visitor);
}
command.setProcessorPlan(container.getCommand().getProcessorPlan());
+ boolean removeLimit = false;
+ if (container instanceof ExistsCriteria) {
+ removeLimit = !((ExistsCriteria)container).shouldEvaluate();
+ } else if (container instanceof ScalarSubquery) {
+ removeLimit = !((ScalarSubquery)container).shouldEvaluate();
+ }
+ if (removeLimit && command.getLimit() != null && command.getLimit().isImplicit()) {
+ command.setLimit(null);
+ }
container.setCommand(command);
}
@@ -432,8 +441,9 @@
childOffset = query.getLimit().getOffset();
}
RulePushLimit.combineLimits(limitNode, metadata, limit, offset, childLimit, childOffset);
-
- query.setLimit(new Limit((Expression)limitNode.getProperty(NodeConstants.Info.OFFSET_TUPLE_COUNT), (Expression)limitNode.getProperty(NodeConstants.Info.MAX_TUPLE_LIMIT)));
+ Limit lim = new Limit((Expression)limitNode.getProperty(NodeConstants.Info.OFFSET_TUPLE_COUNT), (Expression)limitNode.getProperty(NodeConstants.Info.MAX_TUPLE_LIMIT));
+ lim.setImplicit(node.hasBooleanProperty(Info.IS_IMPLICIT_LIMIT));
+ query.setLimit(lim);
}
/**
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-03-07 19:20:20 UTC (rev 2972)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleMergeCriteria.java 2011-03-07 21:03:52 UTC (rev 2973)
@@ -426,11 +426,12 @@
}
public boolean planQuery(Collection<GroupSymbol> leftGroups, boolean requireDistinct, PlannedResult plannedResult) throws QueryMetadataException, TeiidComponentException {
- if (plannedResult.query.getLimit() != null || plannedResult.query.getFrom() == null) {
+ if ((plannedResult.query.getLimit() != null && !plannedResult.query.getLimit().isImplicit()) || plannedResult.query.getFrom() == null) {
return false;
}
plannedResult.query = (Query)plannedResult.query.clone();
+ plannedResult.query.setLimit(null);
List<GroupSymbol> rightGroups = plannedResult.query.getFrom().getGroups();
Set<SingleElementSymbol> requiredExpressions = new LinkedHashSet<SingleElementSymbol>();
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleRemoveOptionalJoins.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleRemoveOptionalJoins.java 2011-03-07 19:20:20 UTC (rev 2972)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleRemoveOptionalJoins.java 2011-03-07 21:03:52 UTC (rev 2973)
@@ -44,6 +44,7 @@
import org.teiid.query.sql.lang.Criteria;
import org.teiid.query.sql.lang.JoinType;
import org.teiid.query.sql.symbol.AggregateSymbol;
+import org.teiid.query.sql.symbol.Constant;
import org.teiid.query.sql.symbol.GroupSymbol;
import org.teiid.query.sql.visitor.GroupsUsedByElementsVisitor;
import org.teiid.query.util.CommandContext;
@@ -122,7 +123,12 @@
if (isOptional) {
required = requiredForOptional;
correctFrame = true;
- //prevent bridge table removal
+ }
+ if (!Collections.disjoint(optionalNode.getGroups(), required)) {
+ return null;
+ }
+ if (isOptional) {
+ //prevent bridge table removal
HashSet<GroupSymbol> joinGroups = new HashSet<GroupSymbol>();
PlanNode parentNode = joinNode;
while (parentNode.getType() != NodeConstants.Types.PROJECT) {
@@ -144,11 +150,7 @@
}
}
}
- }
- if (!Collections.disjoint(optionalNode.getGroups(), required)) {
- return null;
}
-
JoinType jt = (JoinType)joinNode.getProperty(NodeConstants.Info.JOIN_TYPE);
if (!isOptional &&
@@ -227,7 +229,14 @@
return areAggregatesCardinalityDependent(aggs);
}
case NodeConstants.Types.TUPLE_LIMIT: {
- return true;
+ if (!(parent.getProperty(NodeConstants.Info.MAX_TUPLE_LIMIT) instanceof Constant)
+ || parent.getProperty(NodeConstants.Info.OFFSET_TUPLE_COUNT) != null) {
+ return true;
+ }
+ Constant constant = (Constant)parent.getProperty(NodeConstants.Info.MAX_TUPLE_LIMIT);
+ if (!Integer.valueOf(1).equals(constant.getValue())) {
+ return true;
+ }
}
//we assmue that projects of non-deterministic expressions do not matter
}
Modified: trunk/engine/src/main/java/org/teiid/query/processor/relational/LimitNode.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/relational/LimitNode.java 2011-03-07 19:20:20 UTC (rev 2972)
+++ trunk/engine/src/main/java/org/teiid/query/processor/relational/LimitNode.java 2011-03-07 21:03:52 UTC (rev 2973)
@@ -45,6 +45,7 @@
private int offset;
private int rowCounter;
private boolean offsetPhase = true;
+ private boolean implicit;
public LimitNode(int nodeID, Expression limitExpr, Expression offsetExpr) {
super(nodeID);
@@ -52,6 +53,14 @@
this.offsetExpr = offsetExpr;
}
+ public void setImplicit(boolean implicit) {
+ this.implicit = implicit;
+ }
+
+ public boolean isImplicit() {
+ return implicit;
+ }
+
protected TupleBatch nextBatchDirect() throws BlockedException,
TeiidComponentException,
TeiidProcessingException {
@@ -157,8 +166,8 @@
}
public Object clone() {
-
LimitNode node = new LimitNode(getID(), limitExpr, offsetExpr);
+ node.implicit = this.implicit;
copy(this, node);
node.rowCounter = this.rowCounter;
return node;
Modified: trunk/engine/src/main/java/org/teiid/query/processor/relational/RelationalNodeUtil.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/relational/RelationalNodeUtil.java 2011-03-07 19:20:20 UTC (rev 2972)
+++ trunk/engine/src/main/java/org/teiid/query/processor/relational/RelationalNodeUtil.java 2011-03-07 21:03:52 UTC (rev 2973)
@@ -59,6 +59,10 @@
* @since 4.2
*/
public static boolean shouldExecute(Command command, boolean simplifyCriteria) throws TeiidComponentException, ExpressionEvaluationException {
+ return shouldExecute(command, simplifyCriteria, false);
+ }
+
+ public static boolean shouldExecute(Command command, boolean simplifyCriteria, boolean duringPlanning) throws TeiidComponentException, ExpressionEvaluationException {
int cmdType = command.getType();
Criteria criteria = null;
switch(cmdType) {
@@ -79,7 +83,7 @@
SetQuery union = (SetQuery) queryCommand;
boolean shouldExecute = false;
for (QueryCommand innerQuery : union.getQueryCommands()) {
- boolean shouldInner = shouldExecute(innerQuery, simplifyCriteria);
+ boolean shouldInner = shouldExecute(innerQuery, simplifyCriteria, duringPlanning);
if(shouldInner) {
shouldExecute = true;
break;
@@ -94,7 +98,7 @@
if(criteria == null) {
return true;
- } else if(!EvaluatableVisitor.isFullyEvaluatable(criteria, false)) {
+ } else if(!EvaluatableVisitor.isFullyEvaluatable(criteria, duringPlanning)) {
// If there are elements present in the criteria,
// then we don't know the result, so assume we need to execute
return true;
@@ -125,7 +129,7 @@
if (criteria == null) {
return true;
}
- if(!EvaluatableVisitor.isFullyEvaluatable(criteria, false)) {
+ if(!EvaluatableVisitor.isFullyEvaluatable(criteria, duringPlanning)) {
return true;
} else if(Evaluator.evaluate(criteria)) {
if (simplifyCriteria) {
@@ -142,7 +146,7 @@
if (criteria == null) {
return true;
}
- if(!EvaluatableVisitor.isFullyEvaluatable(criteria, false)) {
+ if(!EvaluatableVisitor.isFullyEvaluatable(criteria, duringPlanning)) {
return true;
} else if(Evaluator.evaluate(criteria)) {
if (simplifyCriteria) {
Modified: trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java 2011-03-07 19:20:20 UTC (rev 2972)
+++ trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java 2011-03-07 21:03:52 UTC (rev 2973)
@@ -68,6 +68,7 @@
import org.teiid.query.optimizer.relational.rules.RulePlaceAccess;
import org.teiid.query.optimizer.relational.rules.RuleMergeCriteria.PlannedResult;
import org.teiid.query.processor.relational.DependentValueSource;
+import org.teiid.query.processor.relational.RelationalNodeUtil;
import org.teiid.query.resolver.ProcedureContainerResolver;
import org.teiid.query.resolver.QueryResolver;
import org.teiid.query.resolver.util.ResolverUtil;
@@ -602,7 +603,7 @@
// Rewrite from clause
From from = query.getFrom();
if(from != null){
- List clauses = new ArrayList(from.getClauses().size());
+ List<FromClause> clauses = new ArrayList<FromClause>(from.getClauses().size());
Iterator clauseIter = from.getClauses().iterator();
while(clauseIter.hasNext()) {
clauses.add( rewriteFromClause(query, (FromClause) clauseIter.next()) );
@@ -1121,17 +1122,23 @@
criteria = rewriteCriteria((TranslateCriteria)criteria);
} else if (criteria instanceof ExistsCriteria) {
ExistsCriteria exists = (ExistsCriteria)criteria;
+ if (exists.shouldEvaluate() && processing) {
+ return getCriteria(evaluator.evaluate(exists, null));
+ }
if (exists.getCommand().getProcessorPlan() == null && exists.getCommand() instanceof Query) {
Query query = (Query)exists.getCommand();
- if (query.getLimit() == null && query.getProjectedSymbols().size() > 1) {
+ if ((query.getLimit() == null || query.getOrderBy() == null) && query.getProjectedSymbols().size() > 1) {
query.getSelect().clearSymbols();
query.getSelect().addSymbol(new ExpressionSymbol("x", new Constant(1))); //$NON-NLS-1$
}
}
- if (exists.shouldEvaluate() && processing) {
- return getCriteria(evaluator.evaluate(exists, null));
- }
rewriteSubqueryContainer((SubqueryContainer)criteria, true);
+ if (!RelationalNodeUtil.shouldExecute(exists.getCommand(), false, true)) {
+ return FALSE_CRITERIA;
+ }
+ if (exists.getCommand().getProcessorPlan() == null) {
+ addImplicitLimit(exists, 1);
+ }
} else if (criteria instanceof SubquerySetCriteria) {
SubquerySetCriteria sub = (SubquerySetCriteria)criteria;
if (isNull(sub.getExpression())) {
@@ -1147,6 +1154,33 @@
return evaluateCriteria(criteria);
}
+ private void addImplicitLimit(SubqueryContainer<QueryCommand> container, int rowLimit) {
+ if (container.getCommand().getLimit() != null) {
+ Limit lim = container.getCommand().getLimit();
+ if (lim.getRowLimit() instanceof Constant) {
+ Constant c = (Constant)lim.getRowLimit();
+ if (!c.isMultiValued() && Integer.valueOf(rowLimit).compareTo((Integer) c.getValue()) <= 0) {
+ lim.setRowLimit(new Constant(rowLimit));
+ if (lim.getRowLimit() == null) {
+ lim.setImplicit(true);
+ container.getCommand().setOrderBy(null);
+ }
+ }
+ }
+ return;
+ }
+ boolean addLimit = true;
+ if (container.getCommand() instanceof Query) {
+ Query query = (Query)container.getCommand();
+ addLimit = !(query.hasAggregates() && query.getGroupBy() == null);
+ }
+ if (addLimit) {
+ Limit lim = new Limit(null, new Constant(rowLimit));
+ lim.setImplicit(true);
+ container.getCommand().setLimit(lim);
+ }
+ }
+
private Criteria rewriteDependentSetCriteria(DependentSetCriteria dsc)
throws TeiidComponentException, TeiidProcessingException{
if (!processing) {
@@ -1196,142 +1230,187 @@
// Walk through crits and collect converted ones
LinkedHashSet<Criteria> newCrits = new LinkedHashSet<Criteria>(crits.size());
- HashMap<Expression, Criteria> exprMap = operator == CompoundCriteria.AND?new HashMap<Expression, Criteria>():null;
+ HashMap<Expression, Criteria> exprMap = new HashMap<Expression, Criteria>();
for (Criteria converted : crits) {
if (rewrite) {
converted = rewriteCriteria(converted);
} else if (converted instanceof CompoundCriteria) {
converted = rewriteCriteria((CompoundCriteria)converted, false);
}
-
- //begin boolean optimizations
- if(TRUE_CRITERIA.equals(converted)) {
- if(operator == CompoundCriteria.OR) {
- // this OR must be true as at least one branch is always true
- return converted;
+ List<Criteria> critList = null;
+ if (converted instanceof CompoundCriteria) {
+ CompoundCriteria other = (CompoundCriteria)converted;
+ if (other.getOperator() == criteria.getOperator()) {
+ critList = other.getCriteria();
}
- } else if(FALSE_CRITERIA.equals(converted)) {
- if(operator == CompoundCriteria.AND) {
- // this AND must be false as at least one branch is always false
- return converted;
- }
- } else if (UNKNOWN_CRITERIA.equals(converted)) {
- if (operator == CompoundCriteria.AND) {
- return FALSE_CRITERIA;
- }
- continue;
- } else {
- if (converted instanceof CompoundCriteria) {
- CompoundCriteria other = (CompoundCriteria)converted;
- if (other.getOperator() == criteria.getOperator()) {
- newCrits.addAll(other.getCriteria());
- continue;
+ }
+ if (critList == null) {
+ critList = Arrays.asList(converted);
+ }
+ for (Criteria criteria2 : critList) {
+ converted = criteria2;
+ //begin boolean optimizations
+ if(TRUE_CRITERIA.equals(converted)) {
+ if(operator == CompoundCriteria.OR) {
+ // this OR must be true as at least one branch is always true
+ return converted;
+ }
+ } else if(FALSE_CRITERIA.equals(converted)) {
+ if(operator == CompoundCriteria.AND) {
+ // this AND must be false as at least one branch is always false
+ return converted;
+ }
+ } else if (UNKNOWN_CRITERIA.equals(converted)) {
+ if (operator == CompoundCriteria.AND) {
+ return FALSE_CRITERIA;
}
- } else if (operator == CompoundCriteria.AND) {
- if (converted instanceof IsNullCriteria) {
- IsNullCriteria inc = (IsNullCriteria)converted;
- if (!inc.isNegated()) {
- Criteria crit = exprMap.get(inc.getExpression());
- if (crit == null) {
- exprMap.put(inc.getExpression(), converted);
- } else if (!(crit instanceof IsNullCriteria)) {
+ } else {
+ if (operator == CompoundCriteria.AND) {
+ if (converted instanceof IsNullCriteria) {
+ IsNullCriteria inc = (IsNullCriteria)converted;
+ if (!inc.isNegated()) {
+ Criteria crit = exprMap.get(inc.getExpression());
+ if (crit == null) {
+ exprMap.put(inc.getExpression(), converted);
+ } else if (!(crit instanceof IsNullCriteria)) {
+ return FALSE_CRITERIA;
+ }
+ }
+ } else if (converted instanceof SetCriteria) {
+ SetCriteria sc = (SetCriteria)converted;
+ Criteria crit = exprMap.get(sc.getExpression());
+ if (crit instanceof IsNullCriteria) {
return FALSE_CRITERIA;
}
- }
- } else if (converted instanceof SetCriteria) {
- SetCriteria sc = (SetCriteria)converted;
- Criteria crit = exprMap.get(sc.getExpression());
- if (crit instanceof IsNullCriteria) {
- return FALSE_CRITERIA;
- }
- if (!sc.isNegated() && sc.isAllConstants()) {
- if (crit == null) {
- exprMap.put(sc.getExpression(), converted);
- } else if (crit instanceof SetCriteria) {
- SetCriteria sc1 = (SetCriteria)crit;
- newCrits.remove(sc1);
- sc1.getValues().retainAll(sc.getValues());
- if (sc1.getValues().isEmpty()) {
- return FALSE_CRITERIA;
- }
- //TODO: single value as compare criteria
- newCrits.add(sc1);
- exprMap.put(sc1.getExpression(), sc1);
- continue;
- } else {
- CompareCriteria cc = (CompareCriteria)crit;
- for (Iterator<Constant> exprIter = sc.getValues().iterator(); exprIter.hasNext();) {
- if (!Evaluator.compare(cc, exprIter.next().getValue(), ((Constant)cc.getRightExpression()).getValue())) {
- exprIter.remove();
- }
- }
- if (sc.getValues().isEmpty()) {
- return FALSE_CRITERIA;
- }
- if (cc.getOperator() != CompareCriteria.EQ) {
- newCrits.remove(cc);
+ if (!sc.isNegated() && sc.isAllConstants()) {
+ if (crit == null) {
+ exprMap.put(sc.getExpression(), converted);
+ } else if (crit instanceof SetCriteria) {
+ SetCriteria sc1 = (SetCriteria)crit;
+ newCrits.remove(sc1);
+ sc1.getValues().retainAll(sc.getValues());
+ if (sc1.getValues().isEmpty()) {
+ return FALSE_CRITERIA;
+ }
//TODO: single value as compare criteria
- exprMap.put(sc.getExpression(), sc);
- } else {
- continue;
- }
- }
- }
- } else if (converted instanceof CompareCriteria) {
- CompareCriteria cc = (CompareCriteria)converted;
- Criteria crit = exprMap.get(cc.getLeftExpression());
- if (crit instanceof IsNullCriteria) {
- return FALSE_CRITERIA;
- }
- if (cc.getRightExpression() instanceof Constant) {
- if (crit == null) {
- exprMap.put(cc.getLeftExpression(), cc);
- } else if (crit instanceof SetCriteria) {
- SetCriteria sc = (SetCriteria)crit;
- boolean modified = false;
- for (Iterator<Constant> exprIter = sc.getValues().iterator(); exprIter.hasNext();) {
- if (!Evaluator.compare(cc, exprIter.next().getValue(), ((Constant)cc.getRightExpression()).getValue())) {
- if (!modified) {
- modified = true;
- newCrits.remove(sc);
+ newCrits.add(sc1);
+ exprMap.put(sc1.getExpression(), sc1);
+ continue;
+ } else {
+ CompareCriteria cc = (CompareCriteria)crit;
+ for (Iterator<Constant> exprIter = sc.getValues().iterator(); exprIter.hasNext();) {
+ if (!Evaluator.compare(cc, exprIter.next().getValue(), ((Constant)cc.getRightExpression()).getValue())) {
+ exprIter.remove();
}
- exprIter.remove();
}
- }
- //TODO: single value as compare criteria
- if (sc.getValues().isEmpty()) {
- return FALSE_CRITERIA;
- }
- if (cc.getOperator() == CompareCriteria.EQ) {
- exprMap.put(cc.getLeftExpression(), cc);
- } else if (modified) {
- newCrits.add(sc);
- exprMap.put(sc.getExpression(), sc);
- continue;
- }
- } else {
- CompareCriteria cc1 = (CompareCriteria)crit;
- if (cc1.getOperator() == CompareCriteria.NE) {
- exprMap.put(cc.getLeftExpression(), cc);
- } else if (cc1.getOperator() == CompareCriteria.EQ) {
- if (!Evaluator.compare(cc1, ((Constant)cc1.getRightExpression()).getValue(), ((Constant)cc.getRightExpression()).getValue())) {
- return FALSE_CRITERIA;
+ if (sc.getValues().isEmpty()) {
+ return FALSE_CRITERIA;
+ }
+ if (cc.getOperator() != CompareCriteria.EQ) {
+ newCrits.remove(cc);
+ //TODO: single value as compare criteria
+ exprMap.put(sc.getExpression(), sc);
+ } else {
+ continue;
+ }
+ }
+ }
+ } else if (converted instanceof CompareCriteria) {
+ CompareCriteria cc = (CompareCriteria)converted;
+ Criteria crit = exprMap.get(cc.getLeftExpression());
+ if (crit instanceof IsNullCriteria) {
+ return FALSE_CRITERIA;
+ }
+ if (cc.getRightExpression() instanceof Constant) {
+ if (crit == null) {
+ exprMap.put(cc.getLeftExpression(), cc);
+ } else if (crit instanceof SetCriteria) {
+ SetCriteria sc = (SetCriteria)crit;
+ boolean modified = false;
+ for (Iterator<Constant> exprIter = sc.getValues().iterator(); exprIter.hasNext();) {
+ if (!Evaluator.compare(cc, exprIter.next().getValue(), ((Constant)cc.getRightExpression()).getValue())) {
+ if (!modified) {
+ modified = true;
+ newCrits.remove(sc);
+ }
+ exprIter.remove();
+ }
}
- continue;
- }
- if (cc.getOperator() == CompareCriteria.EQ) {
- if (!Evaluator.compare(cc1, ((Constant)cc.getRightExpression()).getValue(), ((Constant)cc1.getRightExpression()).getValue())) {
- return FALSE_CRITERIA;
- }
- exprMap.put(cc.getLeftExpression(), cc);
- newCrits.remove(cc1);
- }
- }
- }
- }
- }
- newCrits.add(converted);
- }
+ //TODO: single value as compare criteria
+ if (sc.getValues().isEmpty()) {
+ return FALSE_CRITERIA;
+ }
+ if (cc.getOperator() == CompareCriteria.EQ) {
+ exprMap.put(cc.getLeftExpression(), cc);
+ } else if (modified) {
+ newCrits.add(sc);
+ exprMap.put(sc.getExpression(), sc);
+ continue;
+ }
+ } else {
+ CompareCriteria cc1 = (CompareCriteria)crit;
+ if (cc1.getOperator() == CompareCriteria.NE) {
+ exprMap.put(cc.getLeftExpression(), cc);
+ } else if (cc1.getOperator() == CompareCriteria.EQ) {
+ if (!Evaluator.compare(cc1, ((Constant)cc1.getRightExpression()).getValue(), ((Constant)cc.getRightExpression()).getValue())) {
+ return FALSE_CRITERIA;
+ }
+ continue;
+ }
+ if (cc.getOperator() == CompareCriteria.EQ) {
+ if (!Evaluator.compare(cc1, ((Constant)cc.getRightExpression()).getValue(), ((Constant)cc1.getRightExpression()).getValue())) {
+ return FALSE_CRITERIA;
+ }
+ exprMap.put(cc.getLeftExpression(), cc);
+ newCrits.remove(cc1);
+ }
+ }
+ }
+ }
+ } else {
+ //or
+ if (converted instanceof SetCriteria) {
+ SetCriteria sc = (SetCriteria)converted;
+ if (!sc.isNegated() && sc.isAllConstants()) {
+ Criteria crit = exprMap.get(sc.getExpression());
+ if (crit == null) {
+ exprMap.put(sc.getExpression(), sc);
+ } else if (crit instanceof SetCriteria) {
+ SetCriteria other = (SetCriteria)crit;
+ other.getValues().addAll(sc.getValues());
+ continue;
+ } else {
+ newCrits.remove(crit);
+ CompareCriteria cc = (CompareCriteria)crit;
+ sc.getValues().add(cc.getRightExpression());
+ }
+ }
+ } else if (converted instanceof CompareCriteria) {
+ CompareCriteria cc = (CompareCriteria)converted;
+ if (cc.getOperator() == CompareCriteria.EQ && cc.getRightExpression() instanceof Constant) {
+ Criteria crit = exprMap.get(cc.getLeftExpression());
+ if (crit == null) {
+ exprMap.put(cc.getLeftExpression(), cc);
+ } else if (crit instanceof SetCriteria) {
+ SetCriteria other = (SetCriteria)crit;
+ other.getValues().add(cc.getRightExpression());
+ continue;
+ } else {
+ newCrits.remove(crit);
+ CompareCriteria other = (CompareCriteria)crit;
+ SetCriteria sc = new SetCriteria(cc.getLeftExpression(), new TreeSet<Expression>());
+ sc.setAllConstants(true);
+ sc.getValues().add(cc.getRightExpression());
+ sc.getValues().add(other.getRightExpression());
+ exprMap.put(sc.getExpression(), sc);
+ converted = sc;
+ }
+ }
+ }
+ }
+ newCrits.add(converted);
+ }
+ }
}
if(newCrits.size() == 0) {
@@ -2157,6 +2236,12 @@
return new Constant(evaluator.evaluate(subquery, null), subquery.getType());
}
rewriteSubqueryContainer(subquery, true);
+ if (!RelationalNodeUtil.shouldExecute(subquery.getCommand(), false, true)) {
+ return new Constant(null, subquery.getType());
+ }
+ if (subquery.getCommand().getProcessorPlan() == null) {
+ addImplicitLimit(subquery, 2);
+ }
return expression;
} else if (expression instanceof ExpressionSymbol) {
if (expression instanceof AggregateSymbol) {
@@ -2958,6 +3043,9 @@
private Limit rewriteLimitClause(Limit limit) throws TeiidComponentException, TeiidProcessingException{
if (limit.getOffset() != null) {
limit.setOffset(rewriteExpressionDirect(limit.getOffset()));
+ if (new Constant(0).equals(limit.getOffset())) {
+ limit.setOffset(null);
+ }
}
if (limit.getRowLimit() != null) {
limit.setRowLimit(rewriteExpressionDirect(limit.getRowLimit()));
Modified: trunk/engine/src/main/java/org/teiid/query/sql/lang/Limit.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/lang/Limit.java 2011-03-07 19:20:20 UTC (rev 2972)
+++ trunk/engine/src/main/java/org/teiid/query/sql/lang/Limit.java 2011-03-07 21:03:52 UTC (rev 2973)
@@ -26,7 +26,6 @@
import org.teiid.core.util.HashCodeUtil;
import org.teiid.query.sql.LanguageObject;
import org.teiid.query.sql.LanguageVisitor;
-import org.teiid.query.sql.symbol.Constant;
import org.teiid.query.sql.symbol.Expression;
import org.teiid.query.sql.visitor.SQLStringVisitor;
@@ -36,12 +35,25 @@
private Expression offset;
private Expression rowLimit;
+ private boolean implicit;
public Limit(Expression offset, Expression rowLimit) {
this.offset = offset;
this.rowLimit = rowLimit;
}
+ private Limit() {
+
+ }
+
+ public boolean isImplicit() {
+ return implicit;
+ }
+
+ public void setImplicit(boolean implicit) {
+ this.implicit = implicit;
+ }
+
public Expression getOffset() {
return offset;
}
@@ -75,30 +87,22 @@
return false;
}
Limit other = (Limit)o;
- if (this.offset == null) {
- if (other.offset != null
- && !(other.offset instanceof Constant && ((Constant)other.offset).getValue().equals(new Integer(0)))) {
- return false;
- }
- } else if (this.offset instanceof Constant) {
- if (other.offset == null) {
- if (!((Constant)this.offset).getValue().equals(new Integer(0))) {
- return false;
- }
- } else if (!this.offset.equals(other.offset)) {
- return false;
- }
- } else if (!EquivalenceUtil.areEqual(this.offset, other.offset)) {
+ if (!EquivalenceUtil.areEqual(this.offset, other.offset)) {
return false;
}
return EquivalenceUtil.areEqual(this.rowLimit, other.rowLimit);
}
- public Object clone() {
- if (offset == null) {
- return new Limit(null, (Expression)rowLimit.clone());
+ public Limit clone() {
+ Limit clone = new Limit();
+ clone.implicit = this.implicit;
+ if (this.rowLimit != null) {
+ clone.setRowLimit((Expression) this.rowLimit.clone());
}
- return new Limit((Expression)offset.clone(), (Expression)rowLimit.clone());
+ if (this.offset != null) {
+ clone.setOffset((Expression) this.offset.clone());
+ }
+ return clone;
}
public String toString() {
Modified: trunk/engine/src/test/java/org/teiid/query/optimizer/TestOptimizer.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/optimizer/TestOptimizer.java 2011-03-07 19:20:20 UTC (rev 2972)
+++ trunk/engine/src/test/java/org/teiid/query/optimizer/TestOptimizer.java 2011-03-07 21:03:52 UTC (rev 2973)
@@ -2248,7 +2248,7 @@
/**
* BQT query that is failing
*/
- @Test public void testPushAggregate8() {
+ @Test public void testPushAggregate8() throws Exception {
FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
BasicSourceCapabilities caps = new BasicSourceCapabilities();
caps.setCapabilitySupport(Capability.QUERY_SELECT_EXPRESSION, true);
@@ -2267,13 +2267,13 @@
"SELECT MAX(sa.datevalue) FROM bqt1.smalla AS sb " + //$NON-NLS-1$
"WHERE (sb.intkey = sa.intkey) AND (sa.stringkey = sb.stringkey) ))"; //$NON-NLS-1$
- String sqlOut = "SELECT intkey FROM bqt1.smalla AS sa WHERE (sa.intkey = 46) AND (sa.stringkey = '46') AND (sa.datevalue = (SELECT sa.datevalue FROM bqt1.smalla AS sb WHERE (sb.intkey = sa.intkey) AND (sb.stringkey = sa.stringkey)))"; //$NON-NLS-1$
+ String sqlOut = "SELECT g_0.intkey FROM bqt1.smalla AS g_0 WHERE (g_0.intkey = 46) AND (g_0.stringkey = '46') AND (g_0.datevalue = (SELECT g_0.datevalue FROM bqt1.smalla AS g_1 WHERE (g_1.intkey = g_0.intkey) AND (g_1.stringkey = g_0.stringkey)))"; //$NON-NLS-1$
ProcessorPlan plan = helpPlan(sqlIn,
FakeMetadataFactory.exampleBQTCached(),
null, capFinder,
new String[] {sqlOut},
- SHOULD_SUCCEED );
+ ComparisonMode.EXACT_COMMAND_STRING );
checkNodeTypes(plan, FULL_PUSHDOWN);
}
@@ -6379,7 +6379,7 @@
/**
* previously the subqueries were being pushed too far and then not having the appropriate correlated references
*/
- @Test public void testCorrelatedSubqueryOverJoin() {
+ @Test public void testCorrelatedSubqueryOverJoin() throws Exception {
FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
BasicSourceCapabilities caps = TestOptimizer.getTypicalCapabilities();
caps.setCapabilitySupport(Capability.QUERY_FROM_JOIN_INNER, true);
@@ -6392,7 +6392,8 @@
String sql = "select pm1.g1.e1 from pm1.g1, (select * from pm1.g2) y where (pm1.g1.e1 = y.e1) and exists (select e2 from pm1.g2 where e1 = y.e1) and exists (select e3 from pm1.g2 where e1 = y.e1)"; //$NON-NLS-1$
- ProcessorPlan plan = helpPlan(sql, metadata, null, capFinder, new String[] {"SELECT pm1.g1.e1 FROM pm1.g1, pm1.g2 AS g2__1 WHERE (pm1.g1.e1 = g2__1.e1) AND (EXISTS (SELECT e2 FROM pm1.g2 WHERE e1 = g2__1.e1)) AND (EXISTS (SELECT e3 FROM pm1.g2 WHERE e1 = g2__1.e1))"}, TestOptimizer.SHOULD_SUCCEED); //$NON-NLS-1$
+ ProcessorPlan plan = helpPlan(sql, metadata, null, capFinder,
+ new String[] {"SELECT g_0.e1 FROM pm1.g1 AS g_0, pm1.g2 AS g_1 WHERE (g_0.e1 = g_1.e1) AND (EXISTS (SELECT g_2.e2 FROM pm1.g2 AS g_2 WHERE g_2.e1 = g_1.e1)) AND (EXISTS (SELECT g_3.e3 FROM pm1.g2 AS g_3 WHERE g_3.e1 = g_1.e1))"}, ComparisonMode.EXACT_COMMAND_STRING); //$NON-NLS-1$
checkNodeTypes(plan, FULL_PUSHDOWN);
}
Modified: trunk/engine/src/test/java/org/teiid/query/optimizer/TestSubqueryPushdown.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/optimizer/TestSubqueryPushdown.java 2011-03-07 19:20:20 UTC (rev 2972)
+++ trunk/engine/src/test/java/org/teiid/query/optimizer/TestSubqueryPushdown.java 2011-03-07 21:03:52 UTC (rev 2973)
@@ -27,6 +27,7 @@
import org.junit.Test;
import org.teiid.core.TeiidComponentException;
import org.teiid.core.TeiidProcessingException;
+import org.teiid.query.optimizer.TestOptimizer.ComparisonMode;
import org.teiid.query.optimizer.capabilities.BasicSourceCapabilities;
import org.teiid.query.optimizer.capabilities.FakeCapabilitiesFinder;
import org.teiid.query.optimizer.capabilities.SourceCapabilities.Capability;
@@ -766,7 +767,7 @@
* Even though this situation is essentially the same as above, we don't yet handle it
*/
@Test public void testSubqueryRewriteToJoin3() throws Exception {
- TestQueryRewriter.helpTestRewriteCommand("Select e1 from pm3.g1 where exists (select pm1.g1.e2 FROM pm1.g1 WHERE pm3.g1.e1 = pm1.g1.e1 || 1)", "SELECT e1 FROM pm3.g1 WHERE EXISTS (SELECT pm1.g1.e2 FROM pm1.g1 WHERE concat(pm1.g1.e1, '1') = pm3.g1.e1)", FakeMetadataFactory.example4());
+ TestQueryRewriter.helpTestRewriteCommand("Select e1 from pm3.g1 where exists (select pm1.g1.e2 FROM pm1.g1 WHERE pm3.g1.e1 = pm1.g1.e1 || 1)", "SELECT e1 FROM pm3.g1 WHERE EXISTS (SELECT pm1.g1.e2 FROM pm1.g1 WHERE concat(pm1.g1.e1, '1') = pm3.g1.e1 LIMIT 1)", FakeMetadataFactory.example4());
}
@Test public void testSubqueryRewriteToJoinWithOtherCriteria() throws Exception {
Modified: trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java 2011-03-07 19:20:20 UTC (rev 2972)
+++ trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java 2011-03-07 21:03:52 UTC (rev 2973)
@@ -22,9 +22,7 @@
package org.teiid.query.parser;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static org.junit.Assert.*;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
@@ -6435,9 +6433,8 @@
From from = new From(Arrays.asList(new Object[] {new UnaryFromClause(new GroupSymbol("a"))})); //$NON-NLS-1$
query.setSelect(select);
query.setFrom(from);
- query.setLimit(new Limit(new Constant(new Integer(0)), new Constant(new Integer(100))));
+ query.setLimit(new Limit(null, new Constant(new Integer(100))));
helpTest("Select * from a limit 100", "SELECT * FROM a LIMIT 100", query); //$NON-NLS-1$ //$NON-NLS-2$
- helpTest("Select * from a limit 0, 100", "SELECT * FROM a LIMIT 0, 100", query); //$NON-NLS-1$ //$NON-NLS-2$
}
@Test public void testLimitWithOffset() {
Modified: trunk/engine/src/test/java/org/teiid/query/processor/proc/TestProcedureProcessor.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/proc/TestProcedureProcessor.java 2011-03-07 19:20:20 UTC (rev 2972)
+++ trunk/engine/src/test/java/org/teiid/query/processor/proc/TestProcedureProcessor.java 2011-03-07 21:03:52 UTC (rev 2973)
@@ -443,7 +443,7 @@
ProcessorPlan plan = getProcedurePlan(userUpdateStr, metadata);
- helpTestProcessFailure(plan, dataMgr, "Error Code:ERR.015.006.0058 Message:Unable to evaluate (SELECT pm1.g1.e2 FROM pm1.g1): Error Code:ERR.015.006.0058 Message:The command of this scalar subquery returned more than one value: SELECT pm1.g1.e2 FROM pm1.g1", metadata); //$NON-NLS-1$
+ helpTestProcessFailure(plan, dataMgr, "Error Code:ERR.015.006.0058 Message:Unable to evaluate (SELECT pm1.g1.e2 FROM pm1.g1 LIMIT 2): Error Code:ERR.015.006.0058 Message:The command of this scalar subquery returned more than one value: SELECT pm1.g1.e2 FROM pm1.g1 LIMIT 2", metadata); //$NON-NLS-1$
}
// error statement
Modified: trunk/engine/src/test/java/org/teiid/query/processor/relational/TestAccessNode.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/relational/TestAccessNode.java 2011-03-07 19:20:20 UTC (rev 2972)
+++ trunk/engine/src/test/java/org/teiid/query/processor/relational/TestAccessNode.java 2011-03-07 21:03:52 UTC (rev 2973)
@@ -22,15 +22,16 @@
package org.teiid.query.processor.relational;
+import static org.junit.Assert.*;
+
import java.util.Arrays;
+import org.junit.Test;
import org.teiid.common.buffer.BufferManager;
import org.teiid.common.buffer.BufferManagerFactory;
import org.teiid.query.parser.QueryParser;
import org.teiid.query.processor.FakeDataManager;
import org.teiid.query.processor.TestProcessor;
-import org.teiid.query.processor.relational.AccessNode;
-import org.teiid.query.processor.relational.RelationalNodeUtil;
import org.teiid.query.resolver.TestResolver;
import org.teiid.query.sql.lang.Command;
import org.teiid.query.sql.lang.CompoundCriteria;
@@ -44,14 +45,12 @@
import org.teiid.query.unittest.FakeMetadataFactory;
import org.teiid.query.util.CommandContext;
-import junit.framework.TestCase;
-
/**
* @since 4.2
*/
-public class TestAccessNode extends TestCase {
+public class TestAccessNode {
private void helpTestOpen(Command command, String expectedCommand, boolean shouldRegisterRequest) throws Exception {
// Setup
@@ -74,7 +73,7 @@
}
}
- public void testOpen_Defect16059() throws Exception {
+ @Test public void testOpen_Defect16059() throws Exception {
Query query = (Query)TestResolver.helpResolve("SELECT e1, e2 FROM pm1.g1 WHERE e2 = 5 AND ? IS NULL", FakeMetadataFactory.example1Cached(), null); //$NON-NLS-1$
IsNullCriteria nullCrit = (IsNullCriteria)((CompoundCriteria)query.getCriteria()).getCriteria(1);
nullCrit.setExpression(new Constant(null));
@@ -82,7 +81,7 @@
helpTestOpen(query, "SELECT e1, e2 FROM pm1.g1 WHERE e2 = 5", true); //$NON-NLS-1$
}
- public void testOpen_Defect16059_2() throws Exception {
+ @Test public void testOpen_Defect16059_2() throws Exception {
Query query = (Query)TestResolver.helpResolve("SELECT e1, e2 FROM pm1.g1 WHERE e2 = 5 AND ? IS NOT NULL", FakeMetadataFactory.example1Cached(), null); //$NON-NLS-1$
IsNullCriteria nullCrit = (IsNullCriteria)((CompoundCriteria)query.getCriteria()).getCriteria(1);
nullCrit.setExpression(new Constant(null));
@@ -90,7 +89,7 @@
helpTestOpen(query, null, false);
}
- public void testExecCount()throws Exception{
+ @Test public void testExecCount()throws Exception{
// Setup
AccessNode node = new AccessNode(1);
Query query = (Query)TestResolver.helpResolve("SELECT e1, e2 FROM pm1.g1 WHERE e2 = 5", FakeMetadataFactory.example1Cached(), null); //$NON-NLS-1$
@@ -106,7 +105,7 @@
assertEquals(Arrays.asList("SELECT e1, e2 FROM pm1.g1 WHERE e2 = 5"), dataManager.getQueries()); //$NON-NLS-1$
}
- public void testShouldExecuteUpdate() throws Exception {
+ @Test public void testShouldExecuteUpdate() throws Exception {
Update update = new Update();
update.setGroup(new GroupSymbol("test")); //$NON-NLS-1$
@@ -120,7 +119,7 @@
assertFalse(RelationalNodeUtil.shouldExecute(update, false));
}
- public void testShouldExecuteLimitZero() throws Exception {
+ @Test public void testShouldExecuteLimitZero() throws Exception {
Query query = (Query)QueryParser.getQueryParser().parseCommand("SELECT e1, e2 FROM pm1.g1 LIMIT 0"); //$NON-NLS-1$
assertFalse(RelationalNodeUtil.shouldExecute(query, false));
}
Modified: trunk/engine/src/test/java/org/teiid/query/rewriter/TestOrderByRewrite.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/rewriter/TestOrderByRewrite.java 2011-03-07 19:20:20 UTC (rev 2972)
+++ trunk/engine/src/test/java/org/teiid/query/rewriter/TestOrderByRewrite.java 2011-03-07 21:03:52 UTC (rev 2973)
@@ -34,7 +34,6 @@
import org.teiid.core.TeiidProcessingException;
import org.teiid.query.parser.QueryParser;
import org.teiid.query.resolver.QueryResolver;
-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.OrderBy;
@@ -137,7 +136,7 @@
Query resolvedQuery = (Query) getCommand(sql);
helpCheckExpressionsSymbols(resolvedQuery.getOrderBy(),
- new String[] {"(SELECT e2 FROM pm4.g1)"}); //$NON-NLS-1$
+ new String[] {"(SELECT e2 FROM pm4.g1 LIMIT 2)"}); //$NON-NLS-1$
}
@Test public void testOrderBy1() throws Exception {
Modified: trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java 2011-03-07 19:20:20 UTC (rev 2972)
+++ trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java 2011-03-07 21:03:52 UTC (rev 2973)
@@ -672,11 +672,11 @@
}
@Test public void testRewriteOr6() {
- helpTestRewriteCriteria("(0 = 1) OR (4 = 5) OR (pm1.g1.e1 = 'x') OR (pm1.g1.e1 = 'y')", "(pm1.g1.e1 = 'x') OR (pm1.g1.e1 = 'y')"); //$NON-NLS-1$ //$NON-NLS-2$
+ helpTestRewriteCriteria("(0 = 1) OR (4 = 5) OR (pm1.g1.e1 = 'x') OR (pm1.g1.e1 = 'y')", "pm1.g1.e1 IN ('x', 'y')"); //$NON-NLS-1$ //$NON-NLS-2$
}
@Test public void testRewriteOr7() {
- helpTestRewriteCriteria("(pm1.g1.e1 = 'x') OR (pm1.g1.e1 = 'y')", "(pm1.g1.e1 = 'x') OR (pm1.g1.e1 = 'y')"); //$NON-NLS-1$ //$NON-NLS-2$
+ helpTestRewriteCriteria("(pm1.g1.e1 = 'x') OR (pm1.g1.e1 = 'y')", "pm1.g1.e1 IN ('x', 'y')"); //$NON-NLS-1$ //$NON-NLS-2$
}
@Test public void testRewriteAnd1() {
@@ -799,7 +799,7 @@
@Test public void testExistsSubquery() {
helpTestRewriteCommand("SELECT e1 FROM pm1.g1 WHERE EXISTS (SELECT e1 FROM pm1.g2)", //$NON-NLS-1$
- "SELECT e1 FROM pm1.g1 WHERE EXISTS (SELECT e1 FROM pm1.g2)"); //$NON-NLS-1$
+ "SELECT e1 FROM pm1.g1 WHERE EXISTS (SELECT e1 FROM pm1.g2 LIMIT 1)"); //$NON-NLS-1$
}
@Test public void testCompareSubqueryANY() {
@@ -1041,7 +1041,7 @@
String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
rewritProc = rewritProc + "BEGIN\n"; //$NON-NLS-1$
rewritProc = rewritProc + "DECLARE String var1;\n"; //$NON-NLS-1$
- rewritProc = rewritProc + "IF((var1 = 'x') OR (var1 = 'y'))\n"; //$NON-NLS-1$
+ rewritProc = rewritProc + "IF(var1 IN ('x', 'y'))\n"; //$NON-NLS-1$
rewritProc = rewritProc + "BEGIN\n"; //$NON-NLS-1$
rewritProc = rewritProc + "SELECT pm1.g1.e2, null, FALSE, TRUE FROM pm1.g1;\n"; //$NON-NLS-1$
rewritProc = rewritProc + "END\n"; //$NON-NLS-1$
@@ -1230,7 +1230,7 @@
String rewritProc = "CREATE PROCEDURE\n"; //$NON-NLS-1$
rewritProc = rewritProc + "BEGIN\n"; //$NON-NLS-1$
rewritProc = rewritProc + "DECLARE integer var1;\n"; //$NON-NLS-1$
- rewritProc = rewritProc + "UPDATE pm1.g1 SET e1 = 'x' WHERE (CONCAT(e1, 'm') = '1') OR (CONCAT(e1, 'm') = '2');\n"; //$NON-NLS-1$
+ rewritProc = rewritProc + "UPDATE pm1.g1 SET e1 = 'x' WHERE CONCAT(e1, 'm') IN ('1', '2');\n"; //$NON-NLS-1$
rewritProc = rewritProc + "END"; //$NON-NLS-1$
String procReturned = this.getRewritenProcedure(procedure, userQuery,
@@ -2362,6 +2362,10 @@
helpTestRewriteCriteria("pm1.g1.e2 > 5 and pm1.g1.e2 < 2", "1 = 0");
}
+ @Test public void testRewritePredicateOptimizationOr() throws Exception {
+ helpTestRewriteCriteria("pm1.g1.e2 in (5, 6) or pm1.g1.e2 = 2", "pm1.g1.e2 IN (2, 5, 6)");
+ }
+
@Test public void testUDFParse() throws Exception {
FunctionLibrary funcLibrary = new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree("foo", new FakeFunctionMetadataSource()));
FakeMetadataFacade metadata = new FakeMetadataFacade(FakeMetadataFactory.example1Cached().getStore(), funcLibrary);
Modified: trunk/engine/src/test/java/org/teiid/query/sql/lang/TestLimit.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/sql/lang/TestLimit.java 2011-03-07 19:20:20 UTC (rev 2972)
+++ trunk/engine/src/test/java/org/teiid/query/sql/lang/TestLimit.java 2011-03-07 21:03:52 UTC (rev 2973)
@@ -22,13 +22,12 @@
package org.teiid.query.sql.lang;
-import org.teiid.query.sql.lang.Limit;
+import junit.framework.TestCase;
+
import org.teiid.query.sql.symbol.Constant;
import org.teiid.query.sql.symbol.Reference;
-import junit.framework.TestCase;
-
/**
* @since 4.3
*/
@@ -62,8 +61,6 @@
assertFalse(limit1.equals(null));
assertFalse(limit1.equals(limit3));
assertFalse(limit1.equals(limit4));
- assertTrue(limit5.equals(limit6));
- assertTrue(limit6.equals(limit5));
assertFalse(limit6.equals(limit7));
assertFalse(limit7.equals(limit6));
assertFalse(limit5.equals(limit7));
Modified: trunk/test-integration/common/src/test/java/org/teiid/connector/language/TestLanguageUtil.java
===================================================================
--- trunk/test-integration/common/src/test/java/org/teiid/connector/language/TestLanguageUtil.java 2011-03-07 19:20:20 UTC (rev 2972)
+++ trunk/test-integration/common/src/test/java/org/teiid/connector/language/TestLanguageUtil.java 2011-03-07 21:03:52 UTC (rev 2973)
@@ -27,6 +27,8 @@
import java.util.List;
import java.util.Set;
+import junit.framework.TestCase;
+
import org.teiid.cdk.api.TranslationUtility;
import org.teiid.cdk.unittest.FakeTranslationFactory;
import org.teiid.language.Condition;
@@ -34,10 +36,8 @@
import org.teiid.language.LanguageUtil;
import org.teiid.language.Select;
-import junit.framework.TestCase;
-
/**
*/
public class TestLanguageUtil extends TestCase {
@@ -81,7 +81,7 @@
}
public void testSeparateCrit_ORisConjunct() throws Exception {
- helpTestSeparateByAnd("intkey = 1 OR intkey = 2", new String[] { "SmallA.IntKey = 1 OR SmallA.IntKey = 2" }); //$NON-NLS-1$ //$NON-NLS-2$
+ helpTestSeparateByAnd("intkey = 1 OR intnum = 2", new String[] { "SmallA.IntKey = 1 OR SmallA.IntNum = 2" }); //$NON-NLS-1$ //$NON-NLS-2$
}
public void testSeparateCrit_nestedAND() throws Exception {
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-03-07 19:20:20 UTC (rev 2972)
+++ trunk/test-integration/common/src/test/java/org/teiid/dqp/internal/process/TestTPCR.java 2011-03-07 21:03:52 UTC (rev 2973)
@@ -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 > 0.0) AND (left(g_1.C_PHONE, 2) IN ('13', '31', '23', '29', '30', '18', '17')))) AND (NOT (EXISTS (SELECT g_2.O_ORDERKEY, g_2.O_CUSTKEY, g_2.O_ORDERSTATUS, g_2.O_TOTALPRICE, g_2.O_ORDERDATE, g_2.O_ORDERPRIORITY, g_2.O_CLERK, g_2.O_SHIPPRIORITY, g_2.O_COMMENT 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"}, true); //$NON-NLS-1$
+ 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', '17', '18', '23', '29', '30', '31')) 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', '17', '18', '23', '29', '30', '31')))) 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$
TestOptimizer.checkNodeTypes(plan, TestOptimizer.FULL_PUSHDOWN);
}
More information about the teiid-commits
mailing list