[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