[teiid-commits] teiid SVN: r2681 - in branches/7.1.x/engine/src: main/java/org/teiid/query/optimizer/relational and 12 other directories.

teiid-commits at lists.jboss.org teiid-commits at lists.jboss.org
Mon Oct 25 23:49:27 EDT 2010


Author: shawkins
Date: 2010-10-25 23:49:27 -0400 (Mon, 25 Oct 2010)
New Revision: 2681

Modified:
   branches/7.1.x/engine/src/main/java/org/teiid/dqp/internal/datamgr/LanguageBridgeFactory.java
   branches/7.1.x/engine/src/main/java/org/teiid/query/optimizer/relational/PlanToProcessConverter.java
   branches/7.1.x/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java
   branches/7.1.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/CriteriaCapabilityValidatorVisitor.java
   branches/7.1.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleCollapseSource.java
   branches/7.1.x/engine/src/main/java/org/teiid/query/resolver/QueryResolver.java
   branches/7.1.x/engine/src/main/java/org/teiid/query/resolver/command/DeleteResolver.java
   branches/7.1.x/engine/src/main/java/org/teiid/query/resolver/command/InsertResolver.java
   branches/7.1.x/engine/src/main/java/org/teiid/query/resolver/command/UpdateResolver.java
   branches/7.1.x/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
   branches/7.1.x/engine/src/main/java/org/teiid/query/sql/visitor/EvaluatableVisitor.java
   branches/7.1.x/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java
   branches/7.1.x/engine/src/main/resources/org/teiid/query/i18n.properties
   branches/7.1.x/engine/src/test/java/org/teiid/dqp/internal/process/TestPreparedStatement.java
   branches/7.1.x/engine/src/test/java/org/teiid/dqp/internal/process/TestPreparedStatementBatchedUpdate.java
   branches/7.1.x/engine/src/test/java/org/teiid/dqp/service/AutoGenDataService.java
   branches/7.1.x/engine/src/test/java/org/teiid/query/optimizer/TestOptimizer.java
   branches/7.1.x/engine/src/test/java/org/teiid/query/processor/TestInsertProcessing.java
   branches/7.1.x/engine/src/test/java/org/teiid/query/processor/TestProcessor.java
   branches/7.1.x/engine/src/test/java/org/teiid/query/validator/TestValidator.java
Log:
TEIID-1322 shoring up subquery validation and processing with non-query commands

Modified: branches/7.1.x/engine/src/main/java/org/teiid/dqp/internal/datamgr/LanguageBridgeFactory.java
===================================================================
--- branches/7.1.x/engine/src/main/java/org/teiid/dqp/internal/datamgr/LanguageBridgeFactory.java	2010-10-25 18:30:04 UTC (rev 2680)
+++ branches/7.1.x/engine/src/main/java/org/teiid/dqp/internal/datamgr/LanguageBridgeFactory.java	2010-10-26 03:49:27 UTC (rev 2681)
@@ -631,10 +631,8 @@
 			}
         }
         Class<?> returnType = null;
-        List parameters = sp.getParameters();
         List<Argument> translatedParameters = new ArrayList<Argument>();
-        for (Iterator i = parameters.iterator(); i.hasNext();) {
-        	SPParameter param = (SPParameter)i.next();
+        for (SPParameter param : sp.getParameters()) {
         	Direction direction = Direction.IN;
             switch(param.getParameterType()) {
                 case ParameterInfo.IN:    
@@ -650,13 +648,15 @@
                     continue; //already part of the metadata
                 case ParameterInfo.RETURN_VALUE: 
                 	returnType = param.getClassType();
-                	break;
-                    
+                	continue;
             }
             
             ProcedureParameter metadataParam = metadataFactory.getParameter(param);
             //we can assume for now that all arguments will be literals, which may be multivalued
-            Literal value = (Literal)translate(param.getExpression());
+            Literal value = null;
+            if (direction != Direction.OUT) {
+            	value = (Literal)translate(param.getExpression());
+            }
             Argument arg = new Argument(direction, value, param.getClassType(), metadataParam);
             translatedParameters.add(arg);
         }

Modified: branches/7.1.x/engine/src/main/java/org/teiid/query/optimizer/relational/PlanToProcessConverter.java
===================================================================
--- branches/7.1.x/engine/src/main/java/org/teiid/query/optimizer/relational/PlanToProcessConverter.java	2010-10-25 18:30:04 UTC (rev 2680)
+++ branches/7.1.x/engine/src/main/java/org/teiid/query/optimizer/relational/PlanToProcessConverter.java	2010-10-26 03:49:27 UTC (rev 2681)
@@ -82,6 +82,7 @@
 import org.teiid.query.sql.lang.JoinType;
 import org.teiid.query.sql.lang.OrderBy;
 import org.teiid.query.sql.lang.Query;
+import org.teiid.query.sql.lang.QueryCommand;
 import org.teiid.query.sql.lang.StoredProcedure;
 import org.teiid.query.sql.lang.TableFunctionReference;
 import org.teiid.query.sql.lang.TextTable;
@@ -319,13 +320,15 @@
                         aNode.setShouldEvaluateExpressions(EvaluatableVisitor.needsProcessingEvaluation(command));
                     }
                     
-                    try {
-                        command = (Command)command.clone();
-                        boolean aliasGroups = modelID != null && CapabilitiesUtil.supportsGroupAliases(modelID, metadata, capFinder);
-                        boolean aliasColumns = modelID != null && CapabilitiesUtil.supports(Capability.QUERY_SELECT_EXPRESSION, modelID, metadata, capFinder);
-                        command.acceptVisitor(new AliasGenerator(aliasGroups, !aliasColumns));
-                    } catch (QueryMetadataException err) {
-                        throw new TeiidComponentException(err);
+                    if (command instanceof QueryCommand) {
+	                    try {
+	                        command = (Command)command.clone();
+	                        boolean aliasGroups = modelID != null && CapabilitiesUtil.supportsGroupAliases(modelID, metadata, capFinder);
+	                        boolean aliasColumns = modelID != null && CapabilitiesUtil.supports(Capability.QUERY_SELECT_EXPRESSION, modelID, metadata, capFinder);
+	                        command.acceptVisitor(new AliasGenerator(aliasGroups, !aliasColumns));
+	                    } catch (QueryMetadataException err) {
+	                        throw new TeiidComponentException(err);
+	                    }
                     }
                     aNode.setCommand(command);
                     aNode.setModelName(getRoutingName(node));

Modified: branches/7.1.x/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java
===================================================================
--- branches/7.1.x/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java	2010-10-25 18:30:04 UTC (rev 2680)
+++ branches/7.1.x/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java	2010-10-26 03:49:27 UTC (rev 2681)
@@ -58,6 +58,8 @@
 import org.teiid.query.optimizer.relational.plantree.NodeFactory;
 import org.teiid.query.optimizer.relational.plantree.PlanNode;
 import org.teiid.query.optimizer.relational.plantree.NodeConstants.Info;
+import org.teiid.query.optimizer.relational.rules.CriteriaCapabilityValidatorVisitor;
+import org.teiid.query.optimizer.relational.rules.RuleCollapseSource;
 import org.teiid.query.optimizer.relational.rules.RuleConstants;
 import org.teiid.query.parser.QueryParser;
 import org.teiid.query.processor.ProcessorPlan;
@@ -460,12 +462,6 @@
 	private void addNestedProcedure(PlanNode sourceNode,
 			ProcedureContainer container) throws TeiidComponentException,
 			QueryMetadataException, TeiidProcessingException {
-		//plan any subqueries in criteria/parameters/values
-		for (SubqueryContainer subqueryContainer : ValueIteratorProviderCollectorVisitor.getValueIteratorProviders(container)) {
-    		ProcessorPlan plan = QueryOptimizer.optimizePlan(subqueryContainer.getCommand(), metadata, null, capFinder, analysisRecord, context);
-    		subqueryContainer.getCommand().setProcessorPlan(plan);
-		}
-		
 		String cacheString = "transformation/" + container.getClass().getSimpleName(); //$NON-NLS-1$
 		Command c = (Command)metadata.getFromMetadataCache(container.getGroup().getMetadataID(), cacheString);
 		if (c == null) {
@@ -501,6 +497,20 @@
 			//so that we know what the determinism level is.
 			addNestedCommand(sourceNode, container.getGroup(), container, c, false);
 		}
+		//plan any subqueries in criteria/parameters/values
+		for (SubqueryContainer subqueryContainer : ValueIteratorProviderCollectorVisitor.getValueIteratorProviders(container)) {
+    		ProcessorPlan plan = QueryOptimizer.optimizePlan(subqueryContainer.getCommand(), metadata, null, capFinder, analysisRecord, context);
+    		subqueryContainer.getCommand().setProcessorPlan(plan);
+    		
+    		if (c == null) {
+				RuleCollapseSource.replaceCorrelatedReferences(subqueryContainer);
+			}
+		}
+		
+		if (c == null && !container.getGroup().isTempGroupSymbol() && 
+				!CriteriaCapabilityValidatorVisitor.canPushLanguageObject(container, metadata.getModelID(container.getGroup().getMetadataID()), metadata, capFinder, analysisRecord)) {
+			throw new QueryPlannerException(QueryPlugin.Util.getString("RelationalPlanner.nonpushdown_command", container)); //$NON-NLS-1$
+		}
 	}
 
     PlanNode createStoredProcedurePlan(StoredProcedure storedProc) throws QueryMetadataException, TeiidComponentException, TeiidProcessingException {

Modified: branches/7.1.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/CriteriaCapabilityValidatorVisitor.java
===================================================================
--- branches/7.1.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/CriteriaCapabilityValidatorVisitor.java	2010-10-25 18:30:04 UTC (rev 2680)
+++ branches/7.1.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/CriteriaCapabilityValidatorVisitor.java	2010-10-26 03:49:27 UTC (rev 2681)
@@ -226,7 +226,7 @@
             	return;
             }
             if (! CapabilitiesUtil.supportsScalarFunction(modelID, obj, metadata, capFinder)) {
-                markInvalid(obj, obj.isImplicit()?"":"(implicit) convert" + " Function not supported by source"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                markInvalid(obj, (obj.isImplicit()?"(implicit) convert":"") + " Function not supported by source"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
             }
         } catch(QueryMetadataException e) {
             handleException(new TeiidComponentException(e));
@@ -446,7 +446,7 @@
      * @return
      * @throws TeiidComponentException
      */
-    static Object validateSubqueryPushdown(SubqueryContainer subqueryContainer, Object critNodeModelID, QueryMetadataInterface metadata, CapabilitiesFinder capFinder, AnalysisRecord analysisRecord) throws TeiidComponentException {
+    public static Object validateSubqueryPushdown(SubqueryContainer subqueryContainer, Object critNodeModelID, QueryMetadataInterface metadata, CapabilitiesFinder capFinder, AnalysisRecord analysisRecord) throws TeiidComponentException {
     	ProcessorPlan plan = subqueryContainer.getCommand().getProcessorPlan();
     	if (plan != null) {
 	        if(!(plan instanceof RelationalPlan)) {

Modified: branches/7.1.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleCollapseSource.java
===================================================================
--- branches/7.1.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleCollapseSource.java	2010-10-25 18:30:04 UTC (rev 2680)
+++ branches/7.1.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleCollapseSource.java	2010-10-26 03:49:27 UTC (rev 2681)
@@ -348,35 +348,39 @@
 
 	private void replaceCorrelatedReferences(List<SubqueryContainer> containers) {
 		for (SubqueryContainer container : containers) {
-		    RelationalPlan subqueryPlan = (RelationalPlan)container.getCommand().getProcessorPlan();
-		    if (subqueryPlan == null || !(subqueryPlan.getRootNode() instanceof AccessNode)) {
-		    	continue;
-		    }
-		    AccessNode child = (AccessNode)subqueryPlan.getRootNode();
-		    Command command = child.getCommand();
-		    final SymbolMap map = container.getCommand().getCorrelatedReferences();
-		    if (map != null) {
-		    	ExpressionMappingVisitor visitor = new ExpressionMappingVisitor(null) {
-		    		@Override
-		    		public Expression replaceExpression(
-		    				Expression element) {
-		    			if (element instanceof Reference) {
-		    				Reference ref = (Reference)element;
-		    				Expression replacement = map.getMappedExpression(ref.getExpression());
-		    				if (replacement != null) {
-		    					return replacement;
-		    				}
-		    			}
-		    			return element;
-		    		}
-		    	};
-		    	DeepPostOrderNavigator.doVisit(command, visitor);
-		    }
-		    command.setProcessorPlan(container.getCommand().getProcessorPlan());
-		    container.setCommand(command);
+		    replaceCorrelatedReferences(container);
 		}
 	}
 
+	public static void replaceCorrelatedReferences(SubqueryContainer container) {
+		RelationalPlan subqueryPlan = (RelationalPlan)container.getCommand().getProcessorPlan();
+		if (subqueryPlan == null || !(subqueryPlan.getRootNode() instanceof AccessNode)) {
+			return;
+		}
+		AccessNode child = (AccessNode)subqueryPlan.getRootNode();
+		Command command = child.getCommand();
+		final SymbolMap map = container.getCommand().getCorrelatedReferences();
+		if (map != null) {
+			ExpressionMappingVisitor visitor = new ExpressionMappingVisitor(null) {
+				@Override
+				public Expression replaceExpression(
+						Expression element) {
+					if (element instanceof Reference) {
+						Reference ref = (Reference)element;
+						Expression replacement = map.getMappedExpression(ref.getExpression());
+						if (replacement != null) {
+							return replacement;
+						}
+					}
+					return element;
+				}
+			};
+			DeepPostOrderNavigator.doVisit(command, visitor);
+		}
+		command.setProcessorPlan(container.getCommand().getProcessorPlan());
+		container.setCommand(command);
+	}
+
     private void processLimit(PlanNode node,
                               QueryCommand query, QueryMetadataInterface metadata) {
     	

Modified: branches/7.1.x/engine/src/main/java/org/teiid/query/resolver/QueryResolver.java
===================================================================
--- branches/7.1.x/engine/src/main/java/org/teiid/query/resolver/QueryResolver.java	2010-10-25 18:30:04 UTC (rev 2680)
+++ branches/7.1.x/engine/src/main/java/org/teiid/query/resolver/QueryResolver.java	2010-10-26 03:49:27 UTC (rev 2681)
@@ -58,8 +58,10 @@
 import org.teiid.query.sql.lang.GroupContext;
 import org.teiid.query.sql.lang.ProcedureContainer;
 import org.teiid.query.sql.lang.Query;
+import org.teiid.query.sql.lang.SubqueryContainer;
 import org.teiid.query.sql.lang.UnaryFromClause;
 import org.teiid.query.sql.symbol.GroupSymbol;
+import org.teiid.query.sql.visitor.ValueIteratorProviderCollectorVisitor;
 
 
 /**
@@ -291,5 +293,15 @@
         
         return Collections.EMPTY_MAP;
     }
+    
+	public static void resolveSubqueries(Command command,
+			TempMetadataAdapter metadata, AnalysisRecord analysis)
+			throws QueryResolverException, TeiidComponentException {
+		for (SubqueryContainer container : ValueIteratorProviderCollectorVisitor.getValueIteratorProviders(command)) {
+            QueryResolver.setChildMetadata(container.getCommand(), command);
+            
+            QueryResolver.resolveCommand(container.getCommand(), Collections.EMPTY_MAP, metadata.getMetadata(), analysis);
+        }
+	}
 
 }

Modified: branches/7.1.x/engine/src/main/java/org/teiid/query/resolver/command/DeleteResolver.java
===================================================================
--- branches/7.1.x/engine/src/main/java/org/teiid/query/resolver/command/DeleteResolver.java	2010-10-25 18:30:04 UTC (rev 2680)
+++ branches/7.1.x/engine/src/main/java/org/teiid/query/resolver/command/DeleteResolver.java	2010-10-26 03:49:27 UTC (rev 2681)
@@ -33,6 +33,7 @@
 import org.teiid.query.metadata.TempMetadataAdapter;
 import org.teiid.query.metadata.TempMetadataStore;
 import org.teiid.query.resolver.ProcedureContainerResolver;
+import org.teiid.query.resolver.QueryResolver;
 import org.teiid.query.resolver.util.ResolverVisitor;
 import org.teiid.query.sql.lang.Command;
 import org.teiid.query.sql.lang.Delete;
@@ -58,7 +59,7 @@
         Set<GroupSymbol> groups = new HashSet<GroupSymbol>();
         groups.add(delete.getGroup());
         ResolverVisitor.resolveLanguageObject(delete, groups, delete.getExternalGroupContexts(), metadata);
-
+        QueryResolver.resolveSubqueries(command, metadata, analysis);
     }
     
     /** 

Modified: branches/7.1.x/engine/src/main/java/org/teiid/query/resolver/command/InsertResolver.java
===================================================================
--- branches/7.1.x/engine/src/main/java/org/teiid/query/resolver/command/InsertResolver.java	2010-10-25 18:30:04 UTC (rev 2680)
+++ branches/7.1.x/engine/src/main/java/org/teiid/query/resolver/command/InsertResolver.java	2010-10-26 03:49:27 UTC (rev 2681)
@@ -71,13 +71,14 @@
     public void resolveProceduralCommand(Command command, TempMetadataAdapter metadata, AnalysisRecord analysis) 
         throws QueryMetadataException, QueryResolverException, TeiidComponentException {
 
-
         // Cast to known type
         Insert insert = (Insert) command;
         
-        //variables and values must be resolved separately to account for implicitly defined temp groups
-        resolveList(insert.getValues(), metadata, insert.getExternalGroupContexts(), null);
-        
+        if (insert.getValues() != null) {
+        	QueryResolver.resolveSubqueries(command, metadata, analysis);
+	        //variables and values must be resolved separately to account for implicitly defined temp groups
+	        resolveList(insert.getValues(), metadata, insert.getExternalGroupContexts(), null);
+    	}
         //resolve subquery if there
         if(insert.getQueryExpression() != null) {
         	QueryResolver.setChildMetadata(insert.getQueryExpression(), command);

Modified: branches/7.1.x/engine/src/main/java/org/teiid/query/resolver/command/UpdateResolver.java
===================================================================
--- branches/7.1.x/engine/src/main/java/org/teiid/query/resolver/command/UpdateResolver.java	2010-10-25 18:30:04 UTC (rev 2680)
+++ branches/7.1.x/engine/src/main/java/org/teiid/query/resolver/command/UpdateResolver.java	2010-10-26 03:49:27 UTC (rev 2681)
@@ -39,6 +39,7 @@
 import org.teiid.query.metadata.QueryMetadataInterface;
 import org.teiid.query.metadata.TempMetadataAdapter;
 import org.teiid.query.resolver.ProcedureContainerResolver;
+import org.teiid.query.resolver.QueryResolver;
 import org.teiid.query.resolver.VariableResolver;
 import org.teiid.query.resolver.util.ResolverUtil;
 import org.teiid.query.resolver.util.ResolverVisitor;
@@ -69,6 +70,7 @@
         Set<GroupSymbol> groups = new HashSet<GroupSymbol>();
         groups.add(update.getGroup());
         ResolverVisitor.resolveLanguageObject(update, groups, update.getExternalGroupContexts(), metadata);
+        QueryResolver.resolveSubqueries(command, metadata, analysis);
     }
     
     /** 

Modified: branches/7.1.x/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
===================================================================
--- branches/7.1.x/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java	2010-10-25 18:30:04 UTC (rev 2680)
+++ branches/7.1.x/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java	2010-10-26 03:49:27 UTC (rev 2681)
@@ -2330,9 +2330,12 @@
         //After this method, no longer need to display named parameters
         storedProcedure.setDisplayNamedParameters(false);
         
-        for (Iterator i = storedProcedure.getInputParameters().iterator(); i.hasNext();) {
-            SPParameter param = (SPParameter)i.next();
-            param.setExpression(rewriteExpressionDirect(param.getExpression()));
+        for (SPParameter param : storedProcedure.getInputParameters()) {
+            if (!processing) {
+            	param.setExpression(rewriteExpressionDirect(param.getExpression()));
+            } else if (!(param.getExpression() instanceof Constant)) {
+            	param.setExpression(new Constant(this.evaluator.evaluate(param.getExpression(), null), param.getClassType()));
+            }
         }
         return storedProcedure;
     }

Modified: branches/7.1.x/engine/src/main/java/org/teiid/query/sql/visitor/EvaluatableVisitor.java
===================================================================
--- branches/7.1.x/engine/src/main/java/org/teiid/query/sql/visitor/EvaluatableVisitor.java	2010-10-25 18:30:04 UTC (rev 2680)
+++ branches/7.1.x/engine/src/main/java/org/teiid/query/sql/visitor/EvaluatableVisitor.java	2010-10-26 03:49:27 UTC (rev 2681)
@@ -34,6 +34,7 @@
 import org.teiid.query.sql.LanguageVisitor;
 import org.teiid.query.sql.lang.DependentSetCriteria;
 import org.teiid.query.sql.lang.ExistsCriteria;
+import org.teiid.query.sql.lang.SPParameter;
 import org.teiid.query.sql.lang.StoredProcedure;
 import org.teiid.query.sql.lang.SubqueryCompareCriteria;
 import org.teiid.query.sql.lang.SubquerySetCriteria;
@@ -127,6 +128,11 @@
     
     public void visit(StoredProcedure proc){
 		evaluationNotPossible(EvaluationLevel.PUSH_DOWN);
+		for (SPParameter param : proc.getInputParameters()) {
+			if (!(param.getExpression() instanceof Constant)) {
+				evaluationNotPossible(EvaluationLevel.PROCESSING);
+			}
+		}
     }
     
     public void visit(ScalarSubquery obj){

Modified: branches/7.1.x/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java
===================================================================
--- branches/7.1.x/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java	2010-10-25 18:30:04 UTC (rev 2680)
+++ branches/7.1.x/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java	2010-10-26 03:49:27 UTC (rev 2681)
@@ -39,6 +39,7 @@
 import org.teiid.api.exception.query.QueryMetadataException;
 import org.teiid.api.exception.query.QueryValidatorException;
 import org.teiid.core.TeiidComponentException;
+import org.teiid.core.TeiidException;
 import org.teiid.core.TeiidProcessingException;
 import org.teiid.core.types.DataTypeManager;
 import org.teiid.core.util.EquivalenceUtil;
@@ -192,9 +193,27 @@
 	public void visit(Delete obj) {
     	validateNoXMLUpdates(obj);
         validateHasProjectedSymbols(obj);
-        validateGroupSupportsUpdate(obj.getGroup());
+        GroupSymbol group = obj.getGroup();
+        validateGroupSupportsUpdate(group);
+        Criteria crit = obj.getCriteria();
+        validateVirtualUpdate(group, crit);
     }
 
+	private void validateVirtualUpdate(GroupSymbol group,
+			Criteria crit) {
+		if (crit == null) {
+			return;
+		}
+		try {
+			if (getMetadata().isVirtualGroup(group.getMetadataID()) && 
+					!ValueIteratorProviderCollectorVisitor.getValueIteratorProviders(crit).isEmpty()) {
+				handleValidationError(QueryPlugin.Util.getString("ValidationVisitor.virtual_update_subquery"), crit); //$NON-NLS-1$
+			}
+		} catch (TeiidException e) {
+			handleException(e);
+		}
+	}
+
     public void visit(GroupBy obj) {
     	// Get list of all group by IDs
         List groupBySymbols = obj.getSymbols();
@@ -300,6 +319,7 @@
         validateHasProjectedSymbols(obj);
         validateGroupSupportsUpdate(obj.getGroup());
         validateUpdate(obj);
+        validateVirtualUpdate(obj.getGroup(), obj.getCriteria());
     }
 
     public void visit(Into obj) {
@@ -836,7 +856,7 @@
     
     protected void validateSetClauseList(SetClauseList list) {
     	Set<ElementSymbol> dups = new HashSet<ElementSymbol>();
-	    HashSet changeVars = new HashSet();
+	    HashSet<ElementSymbol> changeVars = new HashSet<ElementSymbol>();
 	    for (SetClause clause : list.getClauses()) {
 	    	ElementSymbol elementID = clause.getSymbol();
 	        if (!changeVars.add(elementID)) {

Modified: branches/7.1.x/engine/src/main/resources/org/teiid/query/i18n.properties
===================================================================
--- branches/7.1.x/engine/src/main/resources/org/teiid/query/i18n.properties	2010-10-25 18:30:04 UTC (rev 2680)
+++ branches/7.1.x/engine/src/main/resources/org/teiid/query/i18n.properties	2010-10-26 03:49:27 UTC (rev 2681)
@@ -193,6 +193,7 @@
 ValidationVisitor.limit_not_valid_for_xml=The limit clause cannot be used on an XML document query.
 ValidationVisitor.translated_or=Translated user criteria must not contain OR criteria
 ValidationVisitor.union_insert = Select into is not allowed under a set operation: {0}.
+ValidationVisitor.virtual_update_subquery = Subqueries are not allowed in the criteria for a virtual UPDATE/DELETE: {0}
 ERR.015.012.0029 = INSERT, UPDATE, and DELETE not allowed on XML documents
 ERR.015.012.0030 = Commands used in stored procedure language not allowed on XML documents
 ERR.015.012.0031 = Queries against XML documents can not have a GROUP By clause
@@ -868,7 +869,9 @@
 translator_not_found=Translator {0} not accessible.
 datasource_not_found=Data Source {0} not accessible.
 
-RequestWorkItem.cache_nondeterministic=Caching command '{0}'' at a session level, but less deterministic functions were evaluated. 
+RequestWorkItem.cache_nondeterministic=Caching command "{0}" at a session level, but less deterministic functions were evaluated. 
 not_found_cache=Results not found in cache
 failed_to_unwrap_connection=Failed to unwrap the source connection.
-connection_factory_not_found=Failed to find the Connection Factory with JNDI name {0}. Please check the name or deploy the Connection Factory with specified name. 
\ No newline at end of file
+connection_factory_not_found=Failed to find the Connection Factory with JNDI name {0}. Please check the name or deploy the Connection Factory with specified name.
+
+RelationalPlanner.nonpushdown_command=Source command "{0}" contains non-pushdown constructs. 
\ No newline at end of file

Modified: branches/7.1.x/engine/src/test/java/org/teiid/dqp/internal/process/TestPreparedStatement.java
===================================================================
--- branches/7.1.x/engine/src/test/java/org/teiid/dqp/internal/process/TestPreparedStatement.java	2010-10-25 18:30:04 UTC (rev 2680)
+++ branches/7.1.x/engine/src/test/java/org/teiid/dqp/internal/process/TestPreparedStatement.java	2010-10-26 03:49:27 UTC (rev 2681)
@@ -381,7 +381,7 @@
 		List<String> values = Arrays.asList("aa "); //$NON-NLS-1$
         FakeDataManager dataManager = new FakeDataManager();
         TestProcessor.sampleData2b(dataManager);
-		helpTestProcessing(preparedSql, values, expected, dataManager, FakeMetadataFactory.example1Cached(), false, false, FakeMetadataFactory.example1VDB());
+		helpTestProcessing(preparedSql, values, expected, dataManager, TestOptimizer.getGenericFinder(), FakeMetadataFactory.example1Cached(), null, false, false, false, FakeMetadataFactory.example1VDB());
     }
     
     @Test(expected=QueryValidatorException.class) public void testLimitValidation() throws Exception {

Modified: branches/7.1.x/engine/src/test/java/org/teiid/dqp/internal/process/TestPreparedStatementBatchedUpdate.java
===================================================================
--- branches/7.1.x/engine/src/test/java/org/teiid/dqp/internal/process/TestPreparedStatementBatchedUpdate.java	2010-10-25 18:30:04 UTC (rev 2680)
+++ branches/7.1.x/engine/src/test/java/org/teiid/dqp/internal/process/TestPreparedStatementBatchedUpdate.java	2010-10-26 03:49:27 UTC (rev 2681)
@@ -29,6 +29,7 @@
 import java.util.List;
 
 import org.junit.Test;
+import org.teiid.query.optimizer.TestOptimizer;
 import org.teiid.query.optimizer.capabilities.BasicSourceCapabilities;
 import org.teiid.query.optimizer.capabilities.FakeCapabilitiesFinder;
 import org.teiid.query.optimizer.capabilities.SourceCapabilities.Capability;
@@ -59,7 +60,7 @@
 		dataManager.addData("UPDATE pm1.g1 SET e1 = ?, e3 = ? WHERE pm1.g1.e2 = ?", new List[] {Arrays.asList(4)}); //$NON-NLS-1$
 		// Source capabilities must support batched updates
         FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
-        BasicSourceCapabilities caps = new BasicSourceCapabilities();
+        BasicSourceCapabilities caps = TestOptimizer.getTypicalCapabilities();
         caps.setCapabilitySupport(Capability.BULK_UPDATE, true);
         capFinder.addCapabilities("pm1", caps); //$NON-NLS-1$
         
@@ -122,7 +123,7 @@
 		
 		// Source capabilities must support batched updates
         FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
-        BasicSourceCapabilities caps = new BasicSourceCapabilities();
+        BasicSourceCapabilities caps = TestOptimizer.getTypicalCapabilities();
         caps.setCapabilitySupport(Capability.BATCHED_UPDATES, true);
         capFinder.addCapabilities("pm1", caps); //$NON-NLS-1$
         
@@ -218,7 +219,7 @@
 		
 		// Source capabilities must support batched updates
         FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
-        BasicSourceCapabilities caps = new BasicSourceCapabilities();
+        BasicSourceCapabilities caps = TestOptimizer.getTypicalCapabilities();
         caps.setCapabilitySupport(Capability.BATCHED_UPDATES, true);
         capFinder.addCapabilities("pm1", caps); //$NON-NLS-1$
         
@@ -311,7 +312,7 @@
 		
 		// Source capabilities must support batched updates
         FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
-        BasicSourceCapabilities caps = new BasicSourceCapabilities();
+        BasicSourceCapabilities caps = TestOptimizer.getTypicalCapabilities();
         caps.setCapabilitySupport(Capability.BATCHED_UPDATES, true);
         capFinder.addCapabilities("pm1", caps); //$NON-NLS-1$
         
@@ -434,7 +435,7 @@
 		
 		// Source capabilities must support batched updates
         FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
-        BasicSourceCapabilities caps = new BasicSourceCapabilities();
+        BasicSourceCapabilities caps = TestOptimizer.getTypicalCapabilities();
         caps.setCapabilitySupport(Capability.BATCHED_UPDATES, true);
         capFinder.addCapabilities("pm1", caps); //$NON-NLS-1$
         

Modified: branches/7.1.x/engine/src/test/java/org/teiid/dqp/service/AutoGenDataService.java
===================================================================
--- branches/7.1.x/engine/src/test/java/org/teiid/dqp/service/AutoGenDataService.java	2010-10-25 18:30:04 UTC (rev 2680)
+++ branches/7.1.x/engine/src/test/java/org/teiid/dqp/service/AutoGenDataService.java	2010-10-26 03:49:27 UTC (rev 2681)
@@ -35,11 +35,11 @@
 import org.teiid.dqp.internal.datamgr.ConnectorWorkItem;
 import org.teiid.dqp.message.AtomicRequestMessage;
 import org.teiid.dqp.message.AtomicResultsMessage;
-import org.teiid.query.optimizer.capabilities.BasicSourceCapabilities;
+import org.teiid.query.optimizer.TestOptimizer;
 import org.teiid.query.optimizer.capabilities.SourceCapabilities;
 import org.teiid.query.sql.symbol.SingleElementSymbol;
+import org.teiid.translator.DataNotAvailableException;
 import org.teiid.translator.TranslatorException;
-import org.teiid.translator.DataNotAvailableException;
 
 
 /**
@@ -56,7 +56,7 @@
     
     public AutoGenDataService() {
     	super("FakeConnector","FakeConnector"); //$NON-NLS-1$ //$NON-NLS-2$
-        caps = new BasicSourceCapabilities();
+        caps = TestOptimizer.getTypicalCapabilities();
     }
 
     public void setRows(int rows) {

Modified: branches/7.1.x/engine/src/test/java/org/teiid/query/optimizer/TestOptimizer.java
===================================================================
--- branches/7.1.x/engine/src/test/java/org/teiid/query/optimizer/TestOptimizer.java	2010-10-25 18:30:04 UTC (rev 2680)
+++ branches/7.1.x/engine/src/test/java/org/teiid/query/optimizer/TestOptimizer.java	2010-10-26 03:49:27 UTC (rev 2681)
@@ -792,14 +792,20 @@
 			new String[] { "UPDATE pm1.g1 SET pm1.g1.e1 = 'MyString', pm1.g1.e2 = 1 WHERE pm1.g1.e3 = TRUE"} ); //$NON-NLS-1$
   	}
   	
-    @Test public void testUpdate2() { 
+    @Test public void testUpdate2() throws Exception { 
+    	BasicSourceCapabilities bsc = TestOptimizer.getTypicalCapabilities();
+    	bsc.setFunctionSupport(SourceSystemFunctions.CONVERT, true);
+    	DefaultCapabilitiesFinder dcf = new DefaultCapabilitiesFinder(bsc);
         helpPlan("Update pm1.g1 Set pm1.g1.e1= LTRIM('MyString'), pm1.g1.e2= 1 where pm1.g1.e2= convert(pm1.g1.e4, integer)", FakeMetadataFactory.example1Cached(), //$NON-NLS-1$
-			new String[] { "UPDATE pm1.g1 SET pm1.g1.e1 = 'MyString', pm1.g1.e2 = 1 WHERE pm1.g1.e2 = convert(pm1.g1.e4, integer)"} ); //$NON-NLS-1$
+			new String[] { "UPDATE pm1.g1 SET e1 = 'MyString', e2 = 1 WHERE pm1.g1.e2 = convert(pm1.g1.e4, integer)"}, dcf, ComparisonMode.EXACT_COMMAND_STRING ); //$NON-NLS-1$
     }
     
-    @Test public void testDelete() { 
+    @Test public void testDelete() throws Exception { 
+    	BasicSourceCapabilities bsc = TestOptimizer.getTypicalCapabilities();
+    	bsc.setFunctionSupport(SourceSystemFunctions.CONVERT, true);
+    	DefaultCapabilitiesFinder dcf = new DefaultCapabilitiesFinder(bsc);
     	helpPlan("Delete from pm1.g1 where pm1.g1.e1 = cast(pm1.g1.e2 AS string)", FakeMetadataFactory.example1Cached(), //$NON-NLS-1$
-			new String[] { "DELETE FROM pm1.g1 WHERE pm1.g1.e1 = cast(pm1.g1.e2 AS string)"} ); //$NON-NLS-1$
+			new String[] { "DELETE FROM pm1.g1 WHERE pm1.g1.e1 = convert(pm1.g1.e2, string)"}, dcf, ComparisonMode.EXACT_COMMAND_STRING ); //$NON-NLS-1$
   	}
 
 	// ############################# TESTS ON EXAMPLE 1 ############################
@@ -4605,11 +4611,10 @@
         checkNodeTypes(plan, FULL_PUSHDOWN);
     }
     
-    @Test public void testUpdateWithElement() {
+    @Test public void testUpdateWithElement() throws Exception {
         FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
         BasicSourceCapabilities caps = new BasicSourceCapabilities();
-        caps.setCapabilitySupport(Capability.CRITERIA_COMPARE_EQ, true);
-        caps.setCapabilitySupport(Capability.CRITERIA_COMPARE_ORDERED, true);        
+        caps.setFunctionSupport(SourceSystemFunctions.ADD_OP, true);        
         capFinder.addCapabilities("BQT1", caps); //$NON-NLS-1$
 
         String sql = "UPDATE BQT1.SmallA SET IntKey = IntKey + 1"; //$NON-NLS-1$
@@ -4618,7 +4623,7 @@
                                       FakeMetadataFactory.exampleBQTCached(),
                                       null, capFinder,
                                       new String[] {"UPDATE BQT1.SmallA SET IntKey = (IntKey + 1)"}, //$NON-NLS-1$ 
-                                      SHOULD_SUCCEED );
+                                      ComparisonMode.EXACT_COMMAND_STRING );
 
         checkNodeTypes(plan, TestOptimizer.FULL_PUSHDOWN);
     }            
@@ -6729,6 +6734,11 @@
             new String[] { "SELECT g_0.e1 FROM pm2.g2 AS g_0 WHERE g_0.e1 = pm2.g1.e1", "SELECT g_0.e1 FROM pm2.g1 AS g_0 WHERE g_0.e2 IN (1, 2)" }, capFinder, ComparisonMode.EXACT_COMMAND_STRING); //$NON-NLS-1$
         checkNodeTypes(plan, new int[] {1}, new Class[] {NestedTableJoinStrategy.class});         
     }
+    
+    @Test public void testUpdatePushdownFails() { 
+        helpPlan("update pm1.g1 set e1 = 1 where exists (select 1 from pm1.g2)", FakeMetadataFactory.example1Cached(), null, //$NON-NLS-1$
+			null, null, false); //$NON-NLS-1$
+    }
 
 	public static final boolean DEBUG = false;
 

Modified: branches/7.1.x/engine/src/test/java/org/teiid/query/processor/TestInsertProcessing.java
===================================================================
--- branches/7.1.x/engine/src/test/java/org/teiid/query/processor/TestInsertProcessing.java	2010-10-25 18:30:04 UTC (rev 2680)
+++ branches/7.1.x/engine/src/test/java/org/teiid/query/processor/TestInsertProcessing.java	2010-10-26 03:49:27 UTC (rev 2681)
@@ -22,6 +22,7 @@
 import org.teiid.query.unittest.FakeMetadataFactory;
 import org.teiid.query.unittest.FakeMetadataObject;
 import org.teiid.query.unittest.FakeMetadataStore;
+import org.teiid.translator.SourceSystemFunctions;
 
 
 public class TestInsertProcessing {
@@ -33,6 +34,7 @@
         FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder(); 
         BasicSourceCapabilities caps = TestOptimizer.getTypicalCapabilities(); 
         caps.setCapabilitySupport(Capability.BATCHED_UPDATES, true); 
+        caps.setFunctionSupport(SourceSystemFunctions.CONVERT, true);
         capFinder.addCapabilities("pm1", caps); //$NON-NLS-1$ 
 
         List pm1g1e = FakeMetadataFactory.createElements(pm1g1, 
@@ -155,8 +157,8 @@
         
         FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder(); 
         BasicSourceCapabilities caps = TestOptimizer.getTypicalCapabilities(); 
- 
-        caps.setCapabilitySupport(Capability.BULK_UPDATE, true); 
+        caps.setCapabilitySupport(Capability.BULK_UPDATE, true);
+        caps.setFunctionSupport(SourceSystemFunctions.CONVERT, true);
         capFinder.addCapabilities("pm1", caps); //$NON-NLS-1$ 
 
         List pm1g1e = FakeMetadataFactory.createElements(pm1g1, 
@@ -195,10 +197,9 @@
         
         FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder(); 
         BasicSourceCapabilities caps = TestOptimizer.getTypicalCapabilities(); 
- 
         caps.setCapabilitySupport(Capability.BULK_UPDATE, false); 
         capFinder.addCapabilities("pm1", caps); //$NON-NLS-1$ 
-
+        caps.setFunctionSupport(SourceSystemFunctions.CONVERT, true);
         List pm1g1e = FakeMetadataFactory.createElements(pm1g1, 
                                     new String[] { "e1", "e2" }, //$NON-NLS-1$ //$NON-NLS-2$ 
                                     new String[] { DataTypeManager.DefaultDataTypes.BIG_INTEGER, DataTypeManager.DefaultDataTypes.FLOAT});

Modified: branches/7.1.x/engine/src/test/java/org/teiid/query/processor/TestProcessor.java
===================================================================
--- branches/7.1.x/engine/src/test/java/org/teiid/query/processor/TestProcessor.java	2010-10-25 18:30:04 UTC (rev 2680)
+++ branches/7.1.x/engine/src/test/java/org/teiid/query/processor/TestProcessor.java	2010-10-26 03:49:27 UTC (rev 2681)
@@ -22,14 +22,8 @@
 
 package org.teiid.query.processor;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.teiid.query.optimizer.TestOptimizer.FULL_PUSHDOWN;
-import static org.teiid.query.optimizer.TestOptimizer.checkNodeTypes;
-import static org.teiid.query.optimizer.TestOptimizer.getTypicalCapabilities;
-import static org.teiid.query.optimizer.TestOptimizer.helpPlan;
+import static org.junit.Assert.*;
+import static org.teiid.query.optimizer.TestOptimizer.*;
 
 import java.math.BigDecimal;
 import java.math.BigInteger;
@@ -89,7 +83,6 @@
 import org.teiid.query.processor.relational.RelationalNode;
 import org.teiid.query.processor.relational.RelationalPlan;
 import org.teiid.query.resolver.QueryResolver;
-import org.teiid.query.resolver.util.BindVariableVisitor;
 import org.teiid.query.rewriter.QueryRewriter;
 import org.teiid.query.sql.lang.Command;
 import org.teiid.query.sql.lang.SPParameter;
@@ -122,29 +115,20 @@
         }
     }
 
-	public static ProcessorPlan helpGetPlan(String sql, QueryMetadataInterface metadata) { 
-        return helpGetPlan(sql, metadata, null);
+	public static ProcessorPlan helpGetPlan(String sql, QueryMetadataInterface metadata) {
+		return helpGetPlan(sql, metadata, new DefaultCapabilitiesFinder());
     }
-    
-    public static ProcessorPlan helpGetPlan(String sql, QueryMetadataInterface metadata, String[] bindings) { 
-        if(DEBUG) System.out.println("\n####################################\n" + sql);  //$NON-NLS-1$
+	
+	public static ProcessorPlan helpGetPlan(String sql, QueryMetadataInterface metadata, CapabilitiesFinder finder) { 
+		if(DEBUG) System.out.println("\n####################################\n" + sql);  //$NON-NLS-1$
 
         Command command = helpParse(sql);   
         
-        // attach bindings
-        if(bindings != null) { 
-            try { 
-                BindVariableVisitor.bindReferences(command, Arrays.asList(bindings), metadata);
-            } catch(Throwable e) {
-                throw new TeiidRuntimeException(e);
-            }
-        }
+    	ProcessorPlan process = helpGetPlan(command, metadata, finder);
         
-    	ProcessorPlan process = helpGetPlan(command, metadata);
-        
         return process;
     }
-
+    
     static ProcessorPlan helpGetPlan(Command command, QueryMetadataInterface metadata) {
         return helpGetPlan(command, metadata, new DefaultCapabilitiesFinder());
     }
@@ -6238,11 +6222,11 @@
         String sql = "update vm1.g39 set e2=3"; //$NON-NLS-1$ 
  
         // Plan query 
-        ProcessorPlan plan = helpGetPlan(sql, FakeMetadataFactory.example1Cached());        
+        ProcessorPlan plan = helpGetPlan(sql, FakeMetadataFactory.example1Cached(), TestOptimizer.getGenericFinder());        
 
         // Construct data manager with data 
         HardcodedDataManager dataManager = new HardcodedDataManager(); 
-        dataManager.addData("SELECT pm1.g1.e2 FROM pm1.g1", //$NON-NLS-1$ 
+        dataManager.addData("SELECT g_0.e2 FROM pm1.g1 AS g_0 WHERE g_0.e2 = 3", //$NON-NLS-1$ 
                             new List[] { Arrays.asList(new Object[] { new Integer(3) } )});
         dataManager.addData("UPDATE pm1.g1 SET e2 = 3 WHERE pm1.g1.e2 = 3", //$NON-NLS-1$ 
                             new List[] { Arrays.asList(new Object[] { new Integer(1) } )});
@@ -7580,6 +7564,21 @@
 
         helpProcess(plan, hdm, expected);
     }
-       
+    
+    @Test public void testStoredProcedureSubqueryInput() {
+    	String sql = "exec pm1.sp2((select e2 from pm1.g1 order by e1 limit 1))"; //$NON-NLS-1$
+    	
+        List[] expected = new List[] {
+        		Arrays.asList("b", 2),
+        };    
+    
+        HardcodedDataManager dataManager = new HardcodedDataManager();
+        dataManager.addData("SELECT pm1.g1.e2, pm1.g1.e1 FROM pm1.g1", new List[] {Arrays.asList(1, "2"), Arrays.asList(3, "4")});
+        dataManager.addData("EXEC pm1.sp2(1)", new List[] {Arrays.asList("b", 2)});
+        ProcessorPlan plan = helpGetPlan(helpParse(sql), FakeMetadataFactory.example1Cached());
+        
+        helpProcess(plan, dataManager, expected);
+    }
+    
     private static final boolean DEBUG = false;
 }

Modified: branches/7.1.x/engine/src/test/java/org/teiid/query/validator/TestValidator.java
===================================================================
--- branches/7.1.x/engine/src/test/java/org/teiid/query/validator/TestValidator.java	2010-10-25 18:30:04 UTC (rev 2680)
+++ branches/7.1.x/engine/src/test/java/org/teiid/query/validator/TestValidator.java	2010-10-26 03:49:27 UTC (rev 2681)
@@ -686,8 +686,12 @@
         
     @Test public void testUpdate2() {
         helpValidate("UPDATE test.group SET e0=1, e0=2", new String[] {"e0"}, exampleMetadata()); //$NON-NLS-1$ //$NON-NLS-2$
-    }    
+    }  
     
+    @Test public void testUpdateSubqueryCriteria() {
+        helpValidate("UPDATE vm1.g1 SET e1=1 WHERE exists (select * from vm1.g1)" , new String[] {"EXISTS (SELECT * FROM vm1.g1)"}, FakeMetadataFactory.example1Cached()); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
     @Test public void testUpdate3() throws Exception {
         QueryMetadataInterface metadata = exampleMetadata();
         



More information about the teiid-commits mailing list