[teiid-commits] teiid SVN: r2752 - 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
Thu Dec 2 16:54:00 EST 2010


Author: shawkins
Date: 2010-12-02 16:53:52 -0500 (Thu, 02 Dec 2010)
New Revision: 2752

Added:
   trunk/engine/src/main/java/org/teiid/query/optimizer/TriggerActionPlanner.java
   trunk/engine/src/main/java/org/teiid/query/processor/proc/ForEachRowPlan.java
   trunk/engine/src/main/java/org/teiid/query/sql/proc/TriggerAction.java
   trunk/engine/src/test/java/org/teiid/query/processor/TestTriggerActions.java
Modified:
   trunk/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java
   trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleChooseJoinStrategy.java
   trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleCollapseSource.java
   trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleMergeCriteria.java
   trunk/engine/src/main/java/org/teiid/query/parser/QueryParser.java
   trunk/engine/src/main/java/org/teiid/query/processor/proc/ExecDynamicSqlInstruction.java
   trunk/engine/src/main/java/org/teiid/query/resolver/ProcedureContainerResolver.java
   trunk/engine/src/main/java/org/teiid/query/resolver/QueryResolver.java
   trunk/engine/src/main/java/org/teiid/query/resolver/VariableResolver.java
   trunk/engine/src/main/java/org/teiid/query/resolver/command/InsertResolver.java
   trunk/engine/src/main/java/org/teiid/query/resolver/command/UpdateProcedureResolver.java
   trunk/engine/src/main/java/org/teiid/query/resolver/command/UpdateResolver.java
   trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
   trunk/engine/src/main/java/org/teiid/query/sql/LanguageVisitor.java
   trunk/engine/src/main/java/org/teiid/query/sql/lang/Command.java
   trunk/engine/src/main/java/org/teiid/query/sql/lang/StoredProcedure.java
   trunk/engine/src/main/java/org/teiid/query/sql/navigator/PreOrPostOrderNavigator.java
   trunk/engine/src/main/java/org/teiid/query/sql/proc/CreateUpdateProcedureCommand.java
   trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java
   trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj
   trunk/engine/src/test/java/org/teiid/query/processor/FakeDataStore.java
   trunk/engine/src/test/java/org/teiid/query/processor/TestProcessor.java
Log:
TEIID-1351 initial check-in of for each row instead of trigger handling.  still need to fix validation and combine with earlier rewrite based logic

Added: trunk/engine/src/main/java/org/teiid/query/optimizer/TriggerActionPlanner.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/TriggerActionPlanner.java	                        (rev 0)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/TriggerActionPlanner.java	2010-12-02 21:53:52 UTC (rev 2752)
@@ -0,0 +1,136 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.query.optimizer;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.teiid.api.exception.query.QueryMetadataException;
+import org.teiid.api.exception.query.QueryResolverException;
+import org.teiid.core.TeiidComponentException;
+import org.teiid.core.TeiidProcessingException;
+import org.teiid.core.id.IDGenerator;
+import org.teiid.language.SQLConstants;
+import org.teiid.query.analysis.AnalysisRecord;
+import org.teiid.query.metadata.QueryMetadataInterface;
+import org.teiid.query.optimizer.capabilities.CapabilitiesFinder;
+import org.teiid.query.optimizer.relational.rules.RuleChooseJoinStrategy;
+import org.teiid.query.processor.ProcessorPlan;
+import org.teiid.query.processor.proc.ForEachRowPlan;
+import org.teiid.query.processor.proc.ProcedurePlan;
+import org.teiid.query.processor.relational.RelationalNode;
+import org.teiid.query.resolver.QueryResolver;
+import org.teiid.query.resolver.util.ResolverUtil;
+import org.teiid.query.rewriter.QueryRewriter;
+import org.teiid.query.sql.LanguageObject;
+import org.teiid.query.sql.ProcedureReservedWords;
+import org.teiid.query.sql.lang.Delete;
+import org.teiid.query.sql.lang.From;
+import org.teiid.query.sql.lang.Insert;
+import org.teiid.query.sql.lang.ProcedureContainer;
+import org.teiid.query.sql.lang.Query;
+import org.teiid.query.sql.lang.QueryCommand;
+import org.teiid.query.sql.lang.Select;
+import org.teiid.query.sql.lang.TranslatableProcedureContainer;
+import org.teiid.query.sql.lang.UnaryFromClause;
+import org.teiid.query.sql.lang.Update;
+import org.teiid.query.sql.proc.CreateUpdateProcedureCommand;
+import org.teiid.query.sql.proc.TriggerAction;
+import org.teiid.query.sql.symbol.ElementSymbol;
+import org.teiid.query.sql.symbol.Expression;
+import org.teiid.query.sql.symbol.ExpressionSymbol;
+import org.teiid.query.sql.symbol.SelectSymbol;
+import org.teiid.query.sql.symbol.SingleElementSymbol;
+import org.teiid.query.util.CommandContext;
+
+
+public final class TriggerActionPlanner {
+	
+	public ProcessorPlan optimize(ProcedureContainer userCommand, TriggerAction ta, IDGenerator idGenerator, QueryMetadataInterface metadata, CapabilitiesFinder capFinder, AnalysisRecord analysisRecord, CommandContext context)
+	throws QueryMetadataException, TeiidComponentException, QueryResolverException, TeiidProcessingException {
+		//TODO consider caching the plans without using the changing vars
+		QueryRewriter.rewrite(ta, null, metadata, context, QueryResolver.getVariableValues(userCommand, true, metadata), userCommand.getType());
+		
+		QueryCommand query = null;
+		Map<ElementSymbol, Expression> params = new HashMap<ElementSymbol, Expression>();
+		
+		if (userCommand instanceof Insert) {
+			Insert insert = (Insert)userCommand;
+			if (insert.getQueryExpression() != null) {
+				query = insert.getQueryExpression();
+			} else {
+				query = new Query();
+				((Query)query).setSelect(new Select(RuleChooseJoinStrategy.createExpressionSymbols(insert.getValues())));
+			}
+		} else if (userCommand instanceof Delete) {
+			query = createOldQuery(userCommand, ta, metadata, params);
+		} else if (userCommand instanceof Update) {
+			query = createOldQuery(userCommand, ta, metadata, params);
+		} else {
+			throw new AssertionError();
+		}
+		
+		for (Map.Entry<String, Expression> entry : QueryResolver.getVariableValues(userCommand, false, metadata).entrySet()) {
+			if (entry.getKey().startsWith(ProcedureReservedWords.INPUTS)) {
+				Expression value = entry.getValue() instanceof SingleElementSymbol ? entry.getValue() : new ExpressionSymbol("x", entry.getValue()); //$NON-NLS-1$
+				params.put(new ElementSymbol(SQLConstants.Reserved.NEW + ElementSymbol.SEPARATOR + SingleElementSymbol.getShortName(entry.getKey())), value);
+				if (userCommand instanceof Update) {
+					((Query)query).getSelect().addSymbol((SelectSymbol) value);
+				}
+			} else {
+				params.put(new ElementSymbol(entry.getKey()), entry.getValue()); 
+			}
+		}
+		ForEachRowPlan result = new ForEachRowPlan();
+		result.setParams(params);
+		ProcessorPlan queryPlan = QueryOptimizer.optimizePlan(query, metadata, idGenerator, capFinder, analysisRecord, context);
+		result.setQueryPlan(queryPlan);
+		result.setLookupMap(RelationalNode.createLookupMap(query.getProjectedSymbols()));
+		ProcedurePlan rowProcedure = (ProcedurePlan)QueryOptimizer.optimizePlan(new CreateUpdateProcedureCommand(ta.getBlock()), metadata, idGenerator, capFinder, analysisRecord, context);
+		result.setRowProcedure(rowProcedure);
+		return result;
+	}
+
+	private QueryCommand createOldQuery(ProcedureContainer userCommand,
+			TriggerAction ta, QueryMetadataInterface metadata,
+			Map<ElementSymbol, Expression> params)
+			throws QueryMetadataException, TeiidComponentException {
+		QueryCommand query;
+		ArrayList<SelectSymbol> selectSymbols = new ArrayList<SelectSymbol>();
+		List<ElementSymbol> allSymbols = ResolverUtil.resolveElementsInGroup(ta.getView(), metadata);
+		for (ElementSymbol elementSymbol : allSymbols) {
+			params.put(new ElementSymbol(SQLConstants.Reserved.OLD + ElementSymbol.SEPARATOR + elementSymbol.getShortName()), elementSymbol);
+			if (userCommand instanceof Update) {
+				//default to old
+				params.put(new ElementSymbol(SQLConstants.Reserved.NEW + ElementSymbol.SEPARATOR + elementSymbol.getShortName()), elementSymbol);
+			}
+		}
+		selectSymbols.addAll(LanguageObject.Util.deepClone(allSymbols, ElementSymbol.class));
+		query = new Query(new Select(selectSymbols), new From(Arrays.asList(new UnaryFromClause(ta.getView()))), ((TranslatableProcedureContainer)userCommand).getCriteria(), null, null);
+		return query;
+	}
+        
+}


Property changes on: trunk/engine/src/main/java/org/teiid/query/optimizer/TriggerActionPlanner.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

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	2010-12-02 15:32:06 UTC (rev 2751)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java	2010-12-02 21:53:52 UTC (rev 2752)
@@ -52,6 +52,7 @@
 import org.teiid.query.metadata.TempMetadataID;
 import org.teiid.query.metadata.TempMetadataStore;
 import org.teiid.query.optimizer.QueryOptimizer;
+import org.teiid.query.optimizer.TriggerActionPlanner;
 import org.teiid.query.optimizer.capabilities.CapabilitiesFinder;
 import org.teiid.query.optimizer.capabilities.SourceCapabilities.Capability;
 import org.teiid.query.optimizer.relational.plantree.NodeConstants;
@@ -100,6 +101,7 @@
 import org.teiid.query.sql.lang.WithQueryCommand;
 import org.teiid.query.sql.navigator.PreOrPostOrderNavigator;
 import org.teiid.query.sql.proc.CreateUpdateProcedureCommand;
+import org.teiid.query.sql.proc.TriggerAction;
 import org.teiid.query.sql.symbol.AllSymbol;
 import org.teiid.query.sql.symbol.GroupSymbol;
 import org.teiid.query.sql.symbol.Reference;
@@ -518,16 +520,17 @@
         PlanNode sourceNode = NodeFactory.getNewNode(NodeConstants.Types.SOURCE);
         sourceNode.setProperty(NodeConstants.Info.ATOMIC_REQUEST, command);
         sourceNode.setProperty(NodeConstants.Info.VIRTUAL_COMMAND, command);
+        boolean usingTriggerAction = false;
         if (command instanceof ProcedureContainer) {
         	ProcedureContainer container = (ProcedureContainer)command;
-        	addNestedProcedure(sourceNode, container);
+        	usingTriggerAction = addNestedProcedure(sourceNode, container);
         }
         sourceNode.addGroups(groups);
 
         attachLast(projectNode, sourceNode);
 
         //for INTO query, attach source and project nodes
-        if(command instanceof Insert){
+        if(!usingTriggerAction && command instanceof Insert){
         	Insert insert = (Insert)command;
         	if (insert.getQueryExpression() != null) {
 	            PlanNode plan = generatePlan(insert.getQueryExpression());
@@ -540,7 +543,7 @@
         return projectNode;
 	}
 
-	private void addNestedProcedure(PlanNode sourceNode,
+	private boolean addNestedProcedure(PlanNode sourceNode,
 			ProcedureContainer container) throws TeiidComponentException,
 			QueryMetadataException, TeiidProcessingException {
 		String cacheString = "transformation/" + container.getClass().getSimpleName(); //$NON-NLS-1$
@@ -558,6 +561,12 @@
 			}
 		}
 		if (c != null) {
+			if (c instanceof TriggerAction) {
+				TriggerAction ta = (TriggerAction)c;
+				ProcessorPlan plan = new TriggerActionPlanner().optimize(container, ta, idGenerator, metadata, capFinder, analysisRecord, context);
+			    sourceNode.setProperty(NodeConstants.Info.PROCESSOR_PLAN, plan);
+			    return true;
+			}
 			if (c.getCacheHint() != null) {
 				if (container instanceof StoredProcedure) {
 					boolean noCache = isNoCacheGroup(metadata, ((StoredProcedure) container).getProcedureID(), option);
@@ -566,7 +575,7 @@
 							container.getGroup().setGlobalTable(true);
 							container.setCacheHint(c.getCacheHint());
 							recordAnnotation(analysisRecord, Annotation.CACHED_PROCEDURE, Priority.LOW, "SimpleQueryResolver.procedure_cache_used", container.getGroup()); //$NON-NLS-1$
-							return;
+							return false;
 						}
 						recordAnnotation(analysisRecord, Annotation.CACHED_PROCEDURE, Priority.MEDIUM, "SimpleQueryResolver.procedure_cache_not_usable", container.getGroup()); //$NON-NLS-1$
 					} else {
@@ -577,7 +586,11 @@
 			//skip the rewrite here, we'll do that in the optimizer
 			//so that we know what the determinism level is.
 			addNestedCommand(sourceNode, container.getGroup(), container, c, false);
+		} else if (!(container instanceof Insert) && !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$
 		}
+		
 		//plan any subqueries in criteria/parameters/values
 		for (SubqueryContainer subqueryContainer : ValueIteratorProviderCollectorVisitor.getValueIteratorProviders(container)) {
     		ProcessorPlan plan = QueryOptimizer.optimizePlan(subqueryContainer.getCommand(), metadata, null, capFinder, analysisRecord, context);
@@ -587,11 +600,7 @@
 				RuleCollapseSource.replaceCorrelatedReferences(subqueryContainer);
 			}
 		}
-		
-		if (c == null && !(container instanceof Insert) && !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$
-		}
+		return false;
 	}
 
     PlanNode createStoredProcedurePlan(StoredProcedure storedProc) throws QueryMetadataException, TeiidComponentException, TeiidProcessingException {

Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleChooseJoinStrategy.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleChooseJoinStrategy.java	2010-12-02 15:32:06 UTC (rev 2751)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleChooseJoinStrategy.java	2010-12-02 21:53:52 UTC (rev 2752)
@@ -168,7 +168,7 @@
     
     private static AtomicInteger EXPRESSION_INDEX = new AtomicInteger(0);
     
-    static List<SingleElementSymbol> createExpressionSymbols(List<Expression> expressions) {
+    public static List<SingleElementSymbol> createExpressionSymbols(List<Expression> expressions) {
         HashMap<Expression, ExpressionSymbol> uniqueExpressions = new HashMap<Expression, ExpressionSymbol>();
         List<SingleElementSymbol> result = new ArrayList<SingleElementSymbol>();
         for (Expression expression : expressions) {

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	2010-12-02 15:32:06 UTC (rev 2751)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleCollapseSource.java	2010-12-02 21:53:52 UTC (rev 2752)
@@ -70,7 +70,6 @@
 import org.teiid.query.sql.navigator.DeepPostOrderNavigator;
 import org.teiid.query.sql.symbol.Expression;
 import org.teiid.query.sql.symbol.GroupSymbol;
-import org.teiid.query.sql.symbol.Reference;
 import org.teiid.query.sql.symbol.SingleElementSymbol;
 import org.teiid.query.sql.util.SymbolMap;
 import org.teiid.query.sql.visitor.ExpressionMappingVisitor;
@@ -366,20 +365,7 @@
 		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;
-				}
-			};
+			ExpressionMappingVisitor visitor = new RuleMergeCriteria.ReferenceReplacementVisitor(map);
 			DeepPostOrderNavigator.doVisit(command, visitor);
 		}
 		command.setProcessorPlan(container.getCommand().getProcessorPlan());

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	2010-12-02 15:32:06 UTC (rev 2751)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleMergeCriteria.java	2010-12-02 21:53:52 UTC (rev 2752)
@@ -87,12 +87,12 @@
 	/**
 	 * Used to replace correlated references
 	 */
-	private final class ReferenceReplacementVisitor extends
+	protected static final class ReferenceReplacementVisitor extends
 			ExpressionMappingVisitor {
 		private final SymbolMap refs;
 		private boolean replacedAny;
 		
-		private ReferenceReplacementVisitor(SymbolMap refs) {
+		ReferenceReplacementVisitor(SymbolMap refs) {
 			super(null);
 			this.refs = refs;
 		}

Modified: trunk/engine/src/main/java/org/teiid/query/parser/QueryParser.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/parser/QueryParser.java	2010-12-02 15:32:06 UTC (rev 2751)
+++ trunk/engine/src/main/java/org/teiid/query/parser/QueryParser.java	2010-12-02 21:53:52 UTC (rev 2752)
@@ -93,6 +93,18 @@
 	    return parseCommand(sql, new ParseInfo());
 	}
 	
+	public Command parseUpdateProcedure(String sql) throws QueryParserException {
+		try{
+            Command result = getSqlParser(sql).updateProcedure(new ParseInfo());
+            result.setCacheHint(SQLParserUtil.getQueryCacheOption(sql));
+            return result;
+        } catch(ParseException pe) {
+            throw convertParserException(pe);
+        } catch(TokenMgrError tme) {
+            throw handleTokenMgrError(tme);
+        }
+	}
+	
 	/**
 	 * Takes a SQL string representing a Command and returns the object
 	 * representation.
@@ -120,7 +132,7 @@
         	if(sql.startsWith(XML_OPEN_BRACKET) || sql.startsWith(XQUERY_DECLARE)) {
             	throw new QueryParserException(tme, QueryPlugin.Util.getString("QueryParser.xqueryCompilation", sql)); //$NON-NLS-1$
             }
-            handleTokenMgrError(tme);
+            throw handleTokenMgrError(tme);
         }
 		return result;
 	}
@@ -155,7 +167,7 @@
             throw convertParserException(pe);
 
         } catch(TokenMgrError tme) {
-            handleTokenMgrError(tme);
+            throw handleTokenMgrError(tme);
         }
         return result;
     }
@@ -187,46 +199,37 @@
             throw convertParserException(pe);
 
         } catch(TokenMgrError tme) {
-            handleTokenMgrError(tme);
+            throw handleTokenMgrError(tme);
         }
         return result;
     }
 
-    private void handleTokenMgrError(TokenMgrError tme) throws QueryParserException{
+    private QueryParserException handleTokenMgrError(TokenMgrError tme) {
 //            LogManager.logError( LogConstants.CTX_QUERY_PARSER, tme, new Object[] {"Exception parsing: ", sql} );
 
-        try {
-            // From TokenMgrError, here is format of lexical error:
-            //
-            // "Lexical error at line " + errorLine + ", column " + errorColumn +
-            // ".  Encountered: " + (EOFSeen ? "<EOF> " : ("\"" +
-            // addEscapes(String.valueOf(curChar)) + "\"") + " (" + (int)curChar + "), ") +
-            // "after : \"" + addEscapes(errorAfter) + "\""
+        // From TokenMgrError, here is format of lexical error:
+        //
+        // "Lexical error at line " + errorLine + ", column " + errorColumn +
+        // ".  Encountered: " + (EOFSeen ? "<EOF> " : ("\"" +
+        // addEscapes(String.valueOf(curChar)) + "\"") + " (" + (int)curChar + "), ") +
+        // "after : \"" + addEscapes(errorAfter) + "\""
 
-            String msg = tme.getMessage();
-            int index = msg.indexOf(LINE_MARKER);
+        String msg = tme.getMessage();
+        int index = msg.indexOf(LINE_MARKER);
+        if(index > 0) {
+            index += LINE_MARKER.length();
+            int lastIndex = msg.indexOf(",", index); //$NON-NLS-1$
+            
+            index = msg.indexOf(COL_MARKER, lastIndex);
             if(index > 0) {
-                index += LINE_MARKER.length();
-                int lastIndex = msg.indexOf(",", index); //$NON-NLS-1$
+                index += COL_MARKER.length();
+                lastIndex = msg.indexOf(".", index); //$NON-NLS-1$
                 
-                index = msg.indexOf(COL_MARKER, lastIndex);
-                if(index > 0) {
-                    index += COL_MARKER.length();
-                    lastIndex = msg.indexOf(".", index); //$NON-NLS-1$
-                    
-                    QueryParserException qpe = new QueryParserException(QueryPlugin.Util.getString("QueryParser.lexicalError", tme.getMessage())); //$NON-NLS-1$
-                    throw qpe;
-                }
-
+                return new QueryParserException(QueryPlugin.Util.getString("QueryParser.lexicalError", tme.getMessage())); //$NON-NLS-1$
             }
 
-        } catch(QueryParserException e) {
-            throw e;
-        } catch(Throwable e) {
-            throw new QueryParserException(e, e.getMessage());
         }
-
-        throw new QueryParserException(QueryPlugin.Util.getString("QueryParser.parsingError", tme.getMessage())); //$NON-NLS-1$
+        return new QueryParserException(QueryPlugin.Util.getString("QueryParser.parsingError", tme.getMessage())); //$NON-NLS-1$
     }
 
 }

Modified: trunk/engine/src/main/java/org/teiid/query/processor/proc/ExecDynamicSqlInstruction.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/proc/ExecDynamicSqlInstruction.java	2010-12-02 15:32:06 UTC (rev 2751)
+++ trunk/engine/src/main/java/org/teiid/query/processor/proc/ExecDynamicSqlInstruction.java	2010-12-02 21:53:52 UTC (rev 2752)
@@ -168,7 +168,7 @@
 
 			// create a new set of variables including vars
 			Map nameValueMap = createVariableValuesMap(localContext);
-            nameValueMap.putAll(QueryResolver.getVariableValues(parentProcCommand.getUserCommand(), metadata));
+            nameValueMap.putAll(QueryResolver.getVariableValues(parentProcCommand.getUserCommand(), false, metadata));
             ValidationVisitor visitor = new ValidationVisitor();
             visitor.setUpdateProc(parentProcCommand);
             Request.validateWithVisitor(visitor, metadata, command);

Added: trunk/engine/src/main/java/org/teiid/query/processor/proc/ForEachRowPlan.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/proc/ForEachRowPlan.java	                        (rev 0)
+++ trunk/engine/src/main/java/org/teiid/query/processor/proc/ForEachRowPlan.java	2010-12-02 21:53:52 UTC (rev 2752)
@@ -0,0 +1,160 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.query.processor.proc;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+import org.teiid.common.buffer.BlockedException;
+import org.teiid.common.buffer.BufferManager;
+import org.teiid.common.buffer.TupleBatch;
+import org.teiid.common.buffer.TupleSource;
+import org.teiid.core.TeiidComponentException;
+import org.teiid.core.TeiidProcessingException;
+import org.teiid.query.processor.BatchCollector;
+import org.teiid.query.processor.ProcessorDataManager;
+import org.teiid.query.processor.ProcessorPlan;
+import org.teiid.query.processor.QueryProcessor;
+import org.teiid.query.sql.lang.Command;
+import org.teiid.query.sql.symbol.ElementSymbol;
+import org.teiid.query.sql.symbol.Expression;
+import org.teiid.query.sql.symbol.SingleElementSymbol;
+import org.teiid.query.util.CommandContext;
+
+public class ForEachRowPlan extends ProcessorPlan {
+	
+	private ProcessorPlan queryPlan;
+	private ProcedurePlan rowProcedure;
+	private Map<ElementSymbol, Expression> params;
+	private Map lookupMap;
+	
+	private ProcessorDataManager dataMgr;
+    private BufferManager bufferMgr;
+    
+    private QueryProcessor queryProcessor;
+    private TupleSource tupleSource;
+    private QueryProcessor rowProcessor;
+    private List<?> currentTuple;
+    private int updateCount;
+
+	@Override
+	public ProcessorPlan clone() {
+		ForEachRowPlan clone = new ForEachRowPlan();
+		clone.setQueryPlan(queryPlan.clone());
+		clone.setRowProcedure((ProcedurePlan) rowProcedure.clone());
+		clone.setParams(params);
+		clone.setLookupMap(lookupMap);
+		return clone;
+	}
+
+	@Override
+	public void close() throws TeiidComponentException {
+		if (this.queryProcessor != null) {
+			this.queryProcessor.closeProcessing();
+			if (this.rowProcessor != null) {
+				this.rowProcessor.closeProcessing();
+			}
+		}
+	}
+
+	@Override
+	public List<SingleElementSymbol> getOutputElements() {
+		return Command.getUpdateCommandSymbol();
+	}
+
+	@Override
+	public void initialize(CommandContext context,
+			ProcessorDataManager dataMgr, BufferManager bufferMgr) {
+		setContext(context);
+		this.dataMgr = dataMgr;
+		this.bufferMgr = bufferMgr;
+	}
+
+	@Override
+	public TupleBatch nextBatch() throws BlockedException,
+			TeiidComponentException, TeiidProcessingException {
+		while (true) {
+			if (currentTuple == null) {
+				currentTuple = tupleSource.nextTuple();
+				if (currentTuple == null) {
+					TupleBatch result = new TupleBatch(1, new List[] {Arrays.asList(updateCount)});
+					result.setTerminationFlag(true);
+					return result;
+				}
+			}
+			if (this.rowProcessor == null) {
+				rowProcedure.reset();
+				this.rowProcessor = new QueryProcessor(rowProcedure, getContext(), this.bufferMgr, this.dataMgr);
+				for (Map.Entry<ElementSymbol, Expression> entry : this.params.entrySet()) {
+					Integer index = (Integer)this.lookupMap.get(entry.getValue());
+					if (index != null) {
+						rowProcedure.getCurrentVariableContext().setValue(entry.getKey(), this.currentTuple.get(index));
+					} else {
+						rowProcedure.getCurrentVariableContext().setValue(entry.getKey(), entry.getValue());
+					}
+				}
+			}
+			//just getting the next batch is enough
+			this.rowProcessor.nextBatch();
+			this.rowProcessor.closeProcessing();
+			this.rowProcessor = null;
+			this.currentTuple = null;
+			this.updateCount++;
+		}		
+	}
+
+	@Override
+	public void open() throws TeiidComponentException, TeiidProcessingException {
+		queryProcessor = new QueryProcessor(queryPlan, getContext(), this.bufferMgr, this.dataMgr);
+		tupleSource = new BatchCollector.BatchProducerTupleSource(queryProcessor);
+	}
+	
+	public void setQueryPlan(ProcessorPlan queryPlan) {
+		this.queryPlan = queryPlan;
+	}
+	
+	public void setRowProcedure(ProcedurePlan rowProcedure) {
+		this.rowProcedure = rowProcedure;
+	}
+	
+	public void setParams(Map<ElementSymbol, Expression> params) {
+		this.params = params;
+	}
+	
+	public void setLookupMap(Map symbolMap) {
+		this.lookupMap = symbolMap;
+	}
+	
+	@Override
+	public void reset() {
+		super.reset();
+		this.queryPlan.reset();
+		this.updateCount = 0;
+		this.currentTuple = null;
+		this.rowProcessor = null;
+		this.queryProcessor = null;
+		this.tupleSource = null;
+	}
+
+}


Property changes on: trunk/engine/src/main/java/org/teiid/query/processor/proc/ForEachRowPlan.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Modified: trunk/engine/src/main/java/org/teiid/query/resolver/ProcedureContainerResolver.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/resolver/ProcedureContainerResolver.java	2010-12-02 15:32:06 UTC (rev 2751)
+++ trunk/engine/src/main/java/org/teiid/query/resolver/ProcedureContainerResolver.java	2010-12-02 21:53:52 UTC (rev 2752)
@@ -32,6 +32,7 @@
 import org.teiid.api.exception.query.QueryResolverException;
 import org.teiid.core.TeiidComponentException;
 import org.teiid.core.types.DataTypeManager;
+import org.teiid.language.SQLConstants;
 import org.teiid.query.QueryPlugin;
 import org.teiid.query.analysis.AnalysisRecord;
 import org.teiid.query.metadata.QueryMetadataInterface;
@@ -45,9 +46,13 @@
 import org.teiid.query.resolver.util.ResolverUtil;
 import org.teiid.query.sql.ProcedureReservedWords;
 import org.teiid.query.sql.lang.Command;
+import org.teiid.query.sql.lang.Delete;
 import org.teiid.query.sql.lang.GroupContext;
+import org.teiid.query.sql.lang.Insert;
 import org.teiid.query.sql.lang.ProcedureContainer;
+import org.teiid.query.sql.lang.Update;
 import org.teiid.query.sql.proc.CreateUpdateProcedureCommand;
+import org.teiid.query.sql.proc.TriggerAction;
 import org.teiid.query.sql.symbol.ElementSymbol;
 import org.teiid.query.sql.symbol.GroupSymbol;
 import org.teiid.query.validator.UpdateValidator;
@@ -92,7 +97,7 @@
         
         QueryParser parser = QueryParser.getQueryParser();
         try {
-            subCommand = parser.parseCommand(plan);
+            subCommand = parser.parseUpdateProcedure(plan);
         } catch(QueryParserException e) {
             throw new QueryResolverException(e, "ERR.015.008.0045", QueryPlugin.Util.getString("ERR.015.008.0045", group)); //$NON-NLS-1$ //$NON-NLS-2$
         }
@@ -107,7 +112,26 @@
             
             cupCommand.setVirtualGroup(procCommand.getGroup());
             cupCommand.setUserCommand(procCommand);
-        } 
+        } else if (subCommand instanceof TriggerAction) {
+        	TriggerAction ta = (TriggerAction)subCommand;
+        	ta.setView(procCommand.getGroup());
+        	TempMetadataAdapter tma = new TempMetadataAdapter(metadata, new TempMetadataStore());
+        	ta.setTemporaryMetadata(tma.getMetadataStore().getData());
+            GroupContext externalGroups = procCommand.getExternalGroupContexts();
+            
+            List<ElementSymbol> viewElements = ResolverUtil.resolveElementsInGroup(ta.getView(), metadata);
+            if (procCommand instanceof Update || procCommand instanceof Insert) {
+            	addChanging(tma.getMetadataStore(), externalGroups, viewElements);
+            	ProcedureContainerResolver.addScalarGroup(SQLConstants.Reserved.NEW, tma.getMetadataStore(), externalGroups, viewElements);
+            }
+            if (procCommand instanceof Update || procCommand instanceof Delete) {
+            	ProcedureContainerResolver.addScalarGroup(SQLConstants.Reserved.OLD, tma.getMetadataStore(), externalGroups, viewElements);
+            }
+            
+            new UpdateProcedureResolver().resolveBlock(new CreateUpdateProcedureCommand(), ta.getBlock(), externalGroups, tma, analysis);
+
+            return subCommand;
+        }
         
         //find the childMetadata using a clean metadata store
         TempMetadataStore childMetadata = new TempMetadataStore();
@@ -176,7 +200,13 @@
         addScalarGroup(ProcedureReservedWords.INPUTS, discoveredMetadata, externalGroups, inputElments);
 
         // Switch type to be boolean for all CHANGING variables
-        List<ElementSymbol> changingElements = new ArrayList<ElementSymbol>(elements.size());
+        addChanging(discoveredMetadata, externalGroups, elements);
+		return externalGroups;
+	}
+
+	private static void addChanging(TempMetadataStore discoveredMetadata,
+			GroupContext externalGroups, List<ElementSymbol> elements) {
+		List<ElementSymbol> changingElements = new ArrayList<ElementSymbol>(elements.size());
         for(int i=0; i<elements.size(); i++) {
             ElementSymbol virtualElmnt = elements.get(i);
             ElementSymbol changeElement = (ElementSymbol)virtualElmnt.clone();
@@ -185,7 +215,6 @@
         }
 
         addScalarGroup(ProcedureReservedWords.CHANGING, discoveredMetadata, externalGroups, changingElements);
-		return externalGroups;
 	}
         
     /** 

Modified: trunk/engine/src/main/java/org/teiid/query/resolver/QueryResolver.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/resolver/QueryResolver.java	2010-12-02 15:32:06 UTC (rev 2751)
+++ trunk/engine/src/main/java/org/teiid/query/resolver/QueryResolver.java	2010-12-02 21:53:52 UTC (rev 2752)
@@ -60,6 +60,7 @@
 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.Expression;
 import org.teiid.query.sql.symbol.GroupSymbol;
 import org.teiid.query.sql.visitor.ValueIteratorProviderCollectorVisitor;
 
@@ -287,12 +288,12 @@
         subCommand.setExternalGroupContexts(parentContext);
     }
     
-    public static Map getVariableValues(Command command, QueryMetadataInterface metadata) throws QueryMetadataException, QueryResolverException, TeiidComponentException {
+    public static Map<String, Expression> getVariableValues(Command command, boolean changingOnly, QueryMetadataInterface metadata) throws QueryMetadataException, QueryResolverException, TeiidComponentException {
         
         CommandResolver resolver = chooseResolver(command, metadata);
         
         if (resolver instanceof VariableResolver) {
-            return ((VariableResolver)resolver).getVariableValues(command, metadata);
+            return ((VariableResolver)resolver).getVariableValues(command, changingOnly, metadata);
         }
         
         return Collections.EMPTY_MAP;

Modified: trunk/engine/src/main/java/org/teiid/query/resolver/VariableResolver.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/resolver/VariableResolver.java	2010-12-02 15:32:06 UTC (rev 2751)
+++ trunk/engine/src/main/java/org/teiid/query/resolver/VariableResolver.java	2010-12-02 21:53:52 UTC (rev 2752)
@@ -29,10 +29,11 @@
 import org.teiid.core.TeiidComponentException;
 import org.teiid.query.metadata.QueryMetadataInterface;
 import org.teiid.query.sql.lang.Command;
+import org.teiid.query.sql.symbol.Expression;
 
 
 public interface VariableResolver {
 
-    Map getVariableValues(Command command, QueryMetadataInterface metadata) throws QueryMetadataException, QueryResolverException, TeiidComponentException;
+    Map<String, Expression> getVariableValues(Command command, boolean changingOnly, QueryMetadataInterface metadata) throws QueryMetadataException, QueryResolverException, TeiidComponentException;
     
 }

Modified: trunk/engine/src/main/java/org/teiid/query/resolver/command/InsertResolver.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/resolver/command/InsertResolver.java	2010-12-02 15:32:06 UTC (rev 2751)
+++ trunk/engine/src/main/java/org/teiid/query/resolver/command/InsertResolver.java	2010-12-02 21:53:52 UTC (rev 2752)
@@ -243,16 +243,21 @@
      * @throws QueryMetadataException 
      * @see org.teiid.query.resolver.CommandResolver#getVariableValues(org.teiid.query.sql.lang.Command, org.teiid.query.metadata.QueryMetadataInterface)
      */
-    public Map getVariableValues(Command command,
+    public Map<String, Expression> getVariableValues(Command command, boolean changingOnly,
                                  QueryMetadataInterface metadata) throws QueryMetadataException, QueryResolverException, TeiidComponentException {
         
         Insert insert = (Insert) command;
         
-        Map result = new HashMap();
+        Map<String, Expression> result = new HashMap<String, Expression>();
         
         // iterate over the variables and values they should be the same number
         Iterator varIter = insert.getVariables().iterator();
-        Iterator valIter = insert.getValues().iterator();
+        Iterator valIter = null;
+        if (insert.getQueryExpression() != null) {
+        	valIter = insert.getQueryExpression().getProjectedSymbols().iterator();
+        } else {
+            valIter = insert.getValues().iterator();
+        }
         while (varIter.hasNext()) {
             ElementSymbol varSymbol = (ElementSymbol) varIter.next();
             
@@ -260,8 +265,10 @@
             String changingKey = ProcedureReservedWords.CHANGING + ElementSymbol.SEPARATOR + varName;
             String inputsKey = ProcedureReservedWords.INPUTS + ElementSymbol.SEPARATOR + varName;
             result.put(changingKey, new Constant(Boolean.TRUE));
-            Object value = valIter.next();
-            result.put(inputsKey, value);
+            if (!changingOnly) {
+	            Object value = valIter.next();
+	            result.put(inputsKey, (Expression)value);
+            }
         }
         
         Collection insertElmnts = ResolverUtil.resolveElementsInGroup(insert.getGroup(), metadata);
@@ -278,7 +285,9 @@
             String changingKey = ProcedureReservedWords.CHANGING + ElementSymbol.SEPARATOR + varName;
             String inputsKey = ProcedureReservedWords.INPUTS + ElementSymbol.SEPARATOR + varName;
             result.put(changingKey, new Constant(Boolean.FALSE));
-            result.put(inputsKey, value);
+            if (!changingOnly) {
+            	result.put(inputsKey, value);
+            }
         }
         
         return result;

Modified: trunk/engine/src/main/java/org/teiid/query/resolver/command/UpdateProcedureResolver.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/resolver/command/UpdateProcedureResolver.java	2010-12-02 15:32:06 UTC (rev 2751)
+++ trunk/engine/src/main/java/org/teiid/query/resolver/command/UpdateProcedureResolver.java	2010-12-02 21:53:52 UTC (rev 2752)
@@ -172,11 +172,11 @@
         symbols.add(updateCount);
 
         ProcedureContainerResolver.addScalarGroup(ProcedureReservedWords.VARIABLES, metadata.getMetadataStore(), externalGroups, symbols);         
-        resolveBlock(procCommand, procCommand.getBlock(), externalGroups, metadata, procCommand.isUpdateProcedure(), analysis);
+        resolveBlock(procCommand, procCommand.getBlock(), externalGroups, metadata, analysis);
     }
 
-	private void resolveBlock(CreateUpdateProcedureCommand command, Block block, GroupContext externalGroups, 
-                              TempMetadataAdapter metadata, boolean isUpdateProcedure, AnalysisRecord analysis)
+	public void resolveBlock(CreateUpdateProcedureCommand command, Block block, GroupContext externalGroups, 
+                              TempMetadataAdapter metadata, AnalysisRecord analysis)
         throws QueryResolverException, QueryMetadataException, TeiidComponentException {
         LogManager.logTrace(org.teiid.logging.LogConstants.CTX_QUERY_RESOLVER, new Object[]{"Resolving block", block}); //$NON-NLS-1$
         
@@ -190,11 +190,11 @@
         
         Iterator stmtIter = block.getStatements().iterator();
         while(stmtIter.hasNext()) {
-            resolveStatement(command, (Statement)stmtIter.next(), externalGroups, variables, metadata, isUpdateProcedure, analysis);
+            resolveStatement(command, (Statement)stmtIter.next(), externalGroups, variables, metadata, analysis);
         }
     }
 
-	private void resolveStatement(CreateUpdateProcedureCommand command, Statement statement, GroupContext externalGroups, GroupSymbol variables, TempMetadataAdapter metadata, boolean isUpdateProcedure, AnalysisRecord analysis)
+	private void resolveStatement(CreateUpdateProcedureCommand command, Statement statement, GroupContext externalGroups, GroupSymbol variables, TempMetadataAdapter metadata, AnalysisRecord analysis)
         throws QueryResolverException, QueryMetadataException, TeiidComponentException {
         LogManager.logTrace(org.teiid.logging.LogConstants.CTX_QUERY_RESOLVER, new Object[]{"Resolving statement", statement}); //$NON-NLS-1$
 
@@ -206,9 +206,9 @@
                 	resolveEmbeddedCommand(metadata, externalGroups, container.getCommand(), analysis);
                 }
                 ResolverVisitor.resolveLanguageObject(ifCrit, null, externalGroups, metadata);
-            	resolveBlock(command, ifStmt.getIfBlock(), externalGroups, metadata, isUpdateProcedure, analysis);
+            	resolveBlock(command, ifStmt.getIfBlock(), externalGroups, metadata, analysis);
                 if(ifStmt.hasElseBlock()) {
-                    resolveBlock(command, ifStmt.getElseBlock(), externalGroups, metadata, isUpdateProcedure, analysis);
+                    resolveBlock(command, ifStmt.getElseBlock(), externalGroups, metadata, analysis);
                 }
                 break;
             case Statement.TYPE_COMMAND:
@@ -308,7 +308,7 @@
                 	resolveEmbeddedCommand(metadata, externalGroups, container.getCommand(), analysis);
                 }
                 ResolverVisitor.resolveLanguageObject(whileCrit, null, externalGroups, metadata);
-                resolveBlock(command, whileStmt.getBlock(), externalGroups, metadata, isUpdateProcedure, analysis);
+                resolveBlock(command, whileStmt.getBlock(), externalGroups, metadata, analysis);
                 break;
             case Statement.TYPE_LOOP:
                 LoopStatement loopStmt = (LoopStatement) statement;
@@ -334,7 +334,7 @@
                 
                 ProcedureContainerResolver.addScalarGroup(groupName, store, externalGroups, symbols);
                 
-                resolveBlock(command, loopStmt.getBlock(), externalGroups, metadata, isUpdateProcedure, analysis);
+                resolveBlock(command, loopStmt.getBlock(), externalGroups, metadata, analysis);
                 break;
             case Statement.TYPE_BREAK:
             case Statement.TYPE_CONTINUE:

Modified: trunk/engine/src/main/java/org/teiid/query/resolver/command/UpdateResolver.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/resolver/command/UpdateResolver.java	2010-12-02 15:32:06 UTC (rev 2751)
+++ trunk/engine/src/main/java/org/teiid/query/resolver/command/UpdateResolver.java	2010-12-02 21:53:52 UTC (rev 2752)
@@ -93,9 +93,8 @@
     /** 
      * @see org.teiid.query.resolver.VariableResolver#getVariableValues(org.teiid.query.sql.lang.Command, org.teiid.query.metadata.QueryMetadataInterface)
      */
-    public Map getVariableValues(Command command,
+    public Map<String, Expression> getVariableValues(Command command, boolean changingOnly,
                                  QueryMetadataInterface metadata) throws QueryMetadataException,
-                                                                 QueryResolverException,
                                                                  TeiidComponentException {
         Map result = new HashMap();
         
@@ -110,7 +109,9 @@
             String changingKey = ProcedureReservedWords.CHANGING + ElementSymbol.SEPARATOR + varName;
             String inputsKey = ProcedureReservedWords.INPUTS + ElementSymbol.SEPARATOR + varName;
             result.put(changingKey, new Constant(Boolean.TRUE));
-            result.put(inputsKey, entry.getValue());
+            if (!changingOnly) {
+            	result.put(inputsKey, entry.getValue());
+            }
             updateVars.add(leftSymbol);
         }
         

Modified: trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java	2010-12-02 15:32:06 UTC (rev 2751)
+++ trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java	2010-12-02 21:53:52 UTC (rev 2752)
@@ -133,6 +133,7 @@
 import org.teiid.query.sql.proc.LoopStatement;
 import org.teiid.query.sql.proc.Statement;
 import org.teiid.query.sql.proc.TranslateCriteria;
+import org.teiid.query.sql.proc.TriggerAction;
 import org.teiid.query.sql.proc.WhileStatement;
 import org.teiid.query.sql.symbol.AggregateSymbol;
 import org.teiid.query.sql.symbol.AliasSymbol;
@@ -285,7 +286,10 @@
                     subCommands.set(i, subCommand);
                 }
                 break;
-            	
+            case Command.TYPE_TRIGGER_ACTION:
+            	TriggerAction ta = (TriggerAction)command;
+            	ta.setBlock(rewriteBlock(ta.getBlock()));
+            	break;
 		}
         
         this.metadata = oldMetadata;
@@ -297,7 +301,7 @@
 								 throws TeiidComponentException, TeiidProcessingException{
         Map oldVariables = variables;
     	if (command.getUserCommand() != null) {
-            variables = QueryResolver.getVariableValues(command.getUserCommand(), metadata);                        
+            variables = QueryResolver.getVariableValues(command.getUserCommand(), false, metadata);                        
             commandType = command.getUserCommand().getType();
     	}
 
@@ -2641,12 +2645,12 @@
 	private Command createUpdateProcedure(ProcedureContainer update, Query query,
 			ProcedureContainer newUpdate) throws QueryResolverException,
 			TeiidComponentException, TeiidProcessingException {
+		Block b = new Block();
+		b.addStatement(new CommandStatement(newUpdate));
 		CreateUpdateProcedureCommand cupc = new CreateUpdateProcedureCommand();
 		Block parent = new Block();
-		Block b = new Block();
 		LoopStatement ls = new LoopStatement(b, query, "X"); //$NON-NLS-1$
 		parent.addStatement(ls);
-		b.addStatement(new CommandStatement(newUpdate));
 		AssignmentStatement as = new AssignmentStatement();
 		ElementSymbol rowsUpdate = new ElementSymbol(ProcedureReservedWords.VARIABLES+ElementSymbol.SEPARATOR+ProcedureReservedWords.ROWS_UPDATED);
 		as.setVariable(rowsUpdate);
@@ -2655,7 +2659,7 @@
 		cupc.setBlock(parent);
 		cupc.setVirtualGroup(update.getGroup());
 		QueryResolver.resolveCommand(cupc, metadata);
-		return rewriteUpdateProcedure(cupc);
+		return rewrite(cupc, metadata, context);
 	}
 
 	private List<Criteria> createPkCriteria(UpdateMapping mapping, Query query,

Modified: trunk/engine/src/main/java/org/teiid/query/sql/LanguageVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/LanguageVisitor.java	2010-12-02 15:32:06 UTC (rev 2751)
+++ trunk/engine/src/main/java/org/teiid/query/sql/LanguageVisitor.java	2010-12-02 21:53:52 UTC (rev 2752)
@@ -138,4 +138,5 @@
     public void visit(XMLParse obj) {}
     public void visit(ExpressionCriteria obj) {}
     public void visit(WithQueryCommand obj) {}
+    public void visit(TriggerAction obj) {}
 }

Modified: trunk/engine/src/main/java/org/teiid/query/sql/lang/Command.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/lang/Command.java	2010-12-02 15:32:06 UTC (rev 2751)
+++ trunk/engine/src/main/java/org/teiid/query/sql/lang/Command.java	2010-12-02 21:53:52 UTC (rev 2752)
@@ -101,6 +101,8 @@
     public static final int TYPE_CREATE = 11;
     
     public static final int TYPE_DROP = 12;
+    
+    public static final int TYPE_TRIGGER_ACTION = 13;
 
     private static List<SingleElementSymbol> updateCommandSymbol;
     

Modified: trunk/engine/src/main/java/org/teiid/query/sql/lang/StoredProcedure.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/lang/StoredProcedure.java	2010-12-02 15:32:06 UTC (rev 2751)
+++ trunk/engine/src/main/java/org/teiid/query/sql/lang/StoredProcedure.java	2010-12-02 21:53:52 UTC (rev 2752)
@@ -34,7 +34,6 @@
 
 import org.teiid.client.metadata.ParameterInfo;
 import org.teiid.query.QueryPlugin;
-import org.teiid.query.metadata.StoredProcedureInfo;
 import org.teiid.query.sql.LanguageVisitor;
 import org.teiid.query.sql.symbol.ElementSymbol;
 import org.teiid.query.sql.symbol.Expression;
@@ -63,9 +62,6 @@
     private Object modelID;
     private String callableName;
 
-    //whether return a scalar value
-    private boolean returnsScalarValue;
-
     //stored procedure is treated as a group
     private GroupSymbol group;
     

Modified: trunk/engine/src/main/java/org/teiid/query/sql/navigator/PreOrPostOrderNavigator.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/navigator/PreOrPostOrderNavigator.java	2010-12-02 15:32:06 UTC (rev 2751)
+++ trunk/engine/src/main/java/org/teiid/query/sql/navigator/PreOrPostOrderNavigator.java	2010-12-02 21:53:52 UTC (rev 2752)
@@ -23,7 +23,6 @@
 package org.teiid.query.sql.navigator;
 
 import java.util.Collection;
-import java.util.Iterator;
 
 import org.teiid.query.sql.LanguageObject;
 import org.teiid.query.sql.LanguageVisitor;
@@ -80,6 +79,7 @@
 import org.teiid.query.sql.proc.LoopStatement;
 import org.teiid.query.sql.proc.RaiseErrorStatement;
 import org.teiid.query.sql.proc.TranslateCriteria;
+import org.teiid.query.sql.proc.TriggerAction;
 import org.teiid.query.sql.proc.WhileStatement;
 import org.teiid.query.sql.symbol.AggregateSymbol;
 import org.teiid.query.sql.symbol.AliasSymbol;
@@ -448,10 +448,9 @@
     public void visit(StoredProcedure obj) {
         preVisitVisitor(obj);
         
-        Collection params = obj.getParameters();
+        Collection<SPParameter> params = obj.getParameters();
         if(params != null && !params.isEmpty()) {
-            for(final Iterator iter = params.iterator(); iter.hasNext();) {
-                SPParameter parameter = (SPParameter) iter.next();
+        	for (SPParameter parameter : params) {
                 Expression expression = parameter.getExpression();
                 visitNode(expression);
             }
@@ -652,6 +651,13 @@
     	postVisitVisitor(obj);
     }
     
+    @Override
+    public void visit(TriggerAction obj) {
+    	preVisitVisitor(obj);
+    	visitNode(obj.getBlock());
+    	postVisitVisitor(obj);
+    }
+    
     public static void doVisit(LanguageObject object, LanguageVisitor visitor, boolean order) {
     	doVisit(object, visitor, order, false);
     }

Modified: trunk/engine/src/main/java/org/teiid/query/sql/proc/CreateUpdateProcedureCommand.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/proc/CreateUpdateProcedureCommand.java	2010-12-02 15:32:06 UTC (rev 2751)
+++ trunk/engine/src/main/java/org/teiid/query/sql/proc/CreateUpdateProcedureCommand.java	2010-12-02 21:53:52 UTC (rev 2752)
@@ -154,7 +154,7 @@
 
         //Clone this class state
         if (this.block != null) {
-            copy.setBlock((Block)this.block.clone());
+            copy.setBlock(this.block.clone());
         }
         if (this.getSymbolMap() != null) {
             copy.setSymbolMap(new HashMap(this.getSymbolMap()));
@@ -164,7 +164,7 @@
             copy.setProjectedSymbols(new ArrayList(this.projectedSymbols));
         }
         if (this.virtualGroup != null) {
-        	copy.virtualGroup = (GroupSymbol)this.virtualGroup.clone();
+        	copy.virtualGroup = this.virtualGroup.clone();
         }
         this.copyMetadataState(copy);
 		return copy;

Added: trunk/engine/src/main/java/org/teiid/query/sql/proc/TriggerAction.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/proc/TriggerAction.java	                        (rev 0)
+++ trunk/engine/src/main/java/org/teiid/query/sql/proc/TriggerAction.java	2010-12-02 21:53:52 UTC (rev 2752)
@@ -0,0 +1,109 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.query.sql.proc;
+
+import java.util.List;
+
+import org.teiid.query.sql.LanguageVisitor;
+import org.teiid.query.sql.lang.Command;
+import org.teiid.query.sql.symbol.GroupSymbol;
+import org.teiid.query.sql.symbol.SingleElementSymbol;
+import org.teiid.query.sql.visitor.SQLStringVisitor;
+
+public class TriggerAction extends Command {
+	
+	private GroupSymbol view;
+	private Block block;
+	
+	public TriggerAction(Block b) {
+		this.block = b;
+	}
+	
+	public Block getBlock() {
+		return block;
+	}
+	
+	public void setBlock(Block block) {
+		this.block = block;
+	}
+	
+	public GroupSymbol getView() {
+		return view;
+	}
+	
+	public void setView(GroupSymbol view) {
+		this.view = view;
+	}
+		
+	@Override
+	public int hashCode() {
+		return block.hashCode();
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj) {
+			return true;
+		}
+		if (!(obj instanceof TriggerAction)) {
+			return false;
+		}
+		TriggerAction other = (TriggerAction) obj;
+		return block.equals(other.block);
+	}
+
+	@Override
+	public String toString() {
+		return SQLStringVisitor.getSQLString(this);
+	}
+	
+	@Override
+	public void acceptVisitor(LanguageVisitor visitor) {
+		visitor.visit(this);
+	}
+	
+	@Override
+	public TriggerAction clone() {
+		TriggerAction clone = new TriggerAction(this.block.clone());
+		if (this.view != null) {
+			clone.setView(view.clone());
+		}
+		return clone;
+	}
+
+	@Override
+	public boolean areResultsCachable() {
+		return false;
+	}
+
+	@Override
+	public List<SingleElementSymbol> getProjectedSymbols() {
+		return Command.getUpdateCommandSymbol();
+	}
+
+	@Override
+	public int getType() {
+		return Command.TYPE_TRIGGER_ACTION;
+	}
+
+}


Property changes on: trunk/engine/src/main/java/org/teiid/query/sql/proc/TriggerAction.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Modified: trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java	2010-12-02 15:32:06 UTC (rev 2751)
+++ trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java	2010-12-02 21:53:52 UTC (rev 2752)
@@ -97,6 +97,7 @@
 import org.teiid.query.sql.proc.RaiseErrorStatement;
 import org.teiid.query.sql.proc.Statement;
 import org.teiid.query.sql.proc.TranslateCriteria;
+import org.teiid.query.sql.proc.TriggerAction;
 import org.teiid.query.sql.proc.WhileStatement;
 import org.teiid.query.sql.symbol.AggregateSymbol;
 import org.teiid.query.sql.symbol.AliasSymbol;
@@ -789,7 +790,7 @@
     }
 
 	private void addWithClause(QueryCommand obj) {
-		if (obj.getWith() != null && !obj.getWith().isEmpty()) {
+		if (obj.getWith() != null) {
     		append(WITH);
     		append(SPACE);
             registerNodes(obj.getWith(), 0);
@@ -1871,6 +1872,18 @@
     public void visit( ExpressionCriteria obj ) {
         visitNode(obj.getExpression());
     }
+    
+    @Override
+    public void visit(TriggerAction obj) {
+    	append(FOR);
+        append(SPACE);
+        append(EACH);
+        append(SPACE);
+        append(ROW);
+        append("\n"); //$NON-NLS-1$
+        addTabs(0);
+    	visitNode(obj.getBlock());
+    }
 
     public static String escapeSinglePart( String part ) {
         if (isReservedWord(part)) {

Modified: trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj
===================================================================
--- trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj	2010-12-02 15:32:06 UTC (rev 2751)
+++ trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj	2010-12-02 21:53:52 UTC (rev 2752)
@@ -452,6 +452,31 @@
 	}
 }
 
+Command updateProcedure(ParseInfo info) :
+{
+	Command command = null;
+}
+{
+	(command = createUpdateProcedure(info) |
+	 command = triggerAction(info))
+	<EOF>
+	{
+		return command;
+	}
+}
+
+TriggerAction triggerAction(ParseInfo info) :
+{
+	Block b = null;
+}
+{
+	<FOR> <EACH> <ROW>
+	b = block(info)
+	{
+		return new TriggerAction(b);
+	}
+}
+
 Command userCommand(ParseInfo info) :
 {
 	Command command = null;

Modified: trunk/engine/src/test/java/org/teiid/query/processor/FakeDataStore.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/FakeDataStore.java	2010-12-02 15:32:06 UTC (rev 2751)
+++ trunk/engine/src/test/java/org/teiid/query/processor/FakeDataStore.java	2010-12-02 21:53:52 UTC (rev 2752)
@@ -30,6 +30,7 @@
 import org.teiid.api.exception.query.QueryMetadataException;
 import org.teiid.client.metadata.ParameterInfo;
 import org.teiid.core.TeiidComponentException;
+import org.teiid.query.metadata.QueryMetadataInterface;
 import org.teiid.query.metadata.StoredProcedureInfo;
 import org.teiid.query.metadata.TempMetadataStore;
 import org.teiid.query.sql.lang.SPParameter;
@@ -43,6 +44,7 @@
 /** 
  * This is sample data go along with FakeMetaDataFactory and FakeDataManager
  */
+ at SuppressWarnings("nls")
 public class FakeDataStore {
     
     // Helper to create a list of elements - used in creating sample data
@@ -55,8 +57,19 @@
         }        
         
         return elements;
-    }     
+    }
     
+    public static List createElements(List elementIDs, QueryMetadataInterface metadata) throws QueryMetadataException, TeiidComponentException { 
+        List elements = new ArrayList();
+        for(int i=0; i<elementIDs.size(); i++) {
+            Object elementID = elementIDs.get(i);            
+            ElementSymbol element = new ElementSymbol(metadata.getFullName(elementID));
+            elements.add(element);
+        }        
+        
+        return elements;
+    }
+    
     private static List getProcResultSetSymbols(List params){
         List result = new ArrayList();
         Iterator iter = params.iterator();
@@ -76,139 +89,19 @@
         return result;
     }
     
-    public static void sampleData1(FakeDataManager dataMgr) throws QueryMetadataException, TeiidComponentException {
-        FakeMetadataFacade metadata = FakeMetadataFactory.example1Cached();
-    
-        // Group pm1.g1
-        FakeMetadataObject groupID = (FakeMetadataObject) metadata.getGroupID("pm1.g1"); //$NON-NLS-1$
-        List elementIDs = metadata.getElementIDsInGroupID(groupID);
-        List elementSymbols = createElements(elementIDs);
-    
-        dataMgr.registerTuples(
-            groupID,
-            elementSymbols,
-            
-            new List[] { 
-                Arrays.asList(new Object[] { "a",   new Integer(0),     Boolean.FALSE,  new Double(2.0) }), //$NON-NLS-1$
-                Arrays.asList(new Object[] { null,  new Integer(1),     Boolean.FALSE,  new Double(1.0) }),
-                Arrays.asList(new Object[] { "a",   new Integer(3),     Boolean.TRUE,   new Double(7.0) }), //$NON-NLS-1$
-                Arrays.asList(new Object[] { "c",   new Integer(1),     Boolean.TRUE,   null }), //$NON-NLS-1$
-                Arrays.asList(new Object[] { "b",   new Integer(2),     Boolean.FALSE,  new Double(0.0) }), //$NON-NLS-1$
-                Arrays.asList(new Object[] { "a",   new Integer(0),     Boolean.FALSE,  new Double(2.0) }) //$NON-NLS-1$
-                } );    
+    public static void sampleData1(FakeDataManager dataMgr, QueryMetadataInterface metadata) throws QueryMetadataException, TeiidComponentException {
+		addTable("pm1.g1", dataMgr, metadata);    
+		addTable("pm1.g2", dataMgr, metadata);
+		addTable("pm1.g3", dataMgr, metadata);    
+		addTable("pm2.g1", dataMgr, metadata);
+		addTable("pm2.g2", dataMgr, metadata);
+		addTable("pm2.g3", dataMgr, metadata);
+		addTable("tm1.g1", dataMgr, metadata);
 
-        // Group pm1.g2
-        groupID = (FakeMetadataObject) metadata.getGroupID("pm1.g2"); //$NON-NLS-1$
-        elementIDs = metadata.getElementIDsInGroupID(groupID);
-        elementSymbols = createElements(elementIDs);
-    
-        dataMgr.registerTuples(
-            groupID,
-            elementSymbols,
-            
-            new List[] { 
-                Arrays.asList(new Object[] { "a",   new Integer(0),     Boolean.FALSE,  new Double(2.0) }), //$NON-NLS-1$
-                Arrays.asList(new Object[] { null,  new Integer(1),     Boolean.FALSE,  new Double(1.0) }),
-                Arrays.asList(new Object[] { "a",   new Integer(3),     Boolean.TRUE,   new Double(7.0) }), //$NON-NLS-1$
-                Arrays.asList(new Object[] { "c",   new Integer(1),     Boolean.TRUE,   null }), //$NON-NLS-1$
-                Arrays.asList(new Object[] { "b",   new Integer(2),     Boolean.FALSE,  new Double(0.0) }), //$NON-NLS-1$
-                Arrays.asList(new Object[] { "a",   new Integer(0),     Boolean.FALSE,  new Double(2.0) }) //$NON-NLS-1$
-                } );    
-
-        // Group pm1.g3
-        groupID = (FakeMetadataObject) metadata.getGroupID("pm1.g3"); //$NON-NLS-1$
-        elementIDs = metadata.getElementIDsInGroupID(groupID);
-        elementSymbols = createElements(elementIDs);
-    
-        dataMgr.registerTuples(
-            groupID,
-            elementSymbols,
-            
-            new List[] { 
-                Arrays.asList(new Object[] { "a",   new Integer(0),     Boolean.FALSE,  new Double(2.0) }), //$NON-NLS-1$
-                Arrays.asList(new Object[] { null,  new Integer(1),     Boolean.FALSE,  new Double(1.0) }),
-                Arrays.asList(new Object[] { "a",   new Integer(3),     Boolean.TRUE,   new Double(7.0) }), //$NON-NLS-1$
-                Arrays.asList(new Object[] { "c",   new Integer(1),     Boolean.TRUE,   null }), //$NON-NLS-1$
-                Arrays.asList(new Object[] { "b",   new Integer(2),     Boolean.FALSE,  new Double(0.0) }), //$NON-NLS-1$
-                Arrays.asList(new Object[] { "a",   new Integer(0),     Boolean.FALSE,  new Double(2.0) }) //$NON-NLS-1$
-                } );    
-            
-        // Group pm2.g1
-        groupID = (FakeMetadataObject) metadata.getGroupID("pm2.g1"); //$NON-NLS-1$
-        elementIDs = metadata.getElementIDsInGroupID(groupID);
-        elementSymbols = createElements(elementIDs);
-    
-        dataMgr.registerTuples(
-            groupID,
-            elementSymbols,
-            
-            new List[] { 
-                Arrays.asList(new Object[] { "a",   new Integer(0),     Boolean.FALSE,  new Double(2.0) }), //$NON-NLS-1$
-                Arrays.asList(new Object[] { null,  new Integer(1),     Boolean.FALSE,  new Double(1.0) }),
-                Arrays.asList(new Object[] { "a",   new Integer(3),     Boolean.TRUE,   new Double(7.0) }), //$NON-NLS-1$
-                Arrays.asList(new Object[] { "c",   new Integer(1),     Boolean.TRUE,   null }), //$NON-NLS-1$
-                Arrays.asList(new Object[] { "b",   new Integer(2),     Boolean.FALSE,  new Double(0.0) }), //$NON-NLS-1$
-                Arrays.asList(new Object[] { "a",   new Integer(0),     Boolean.FALSE,  new Double(2.0) }) //$NON-NLS-1$
-                } );    
-                
-        // Group pm2.g2
-        groupID = (FakeMetadataObject) metadata.getGroupID("pm2.g2"); //$NON-NLS-1$
-        elementIDs = metadata.getElementIDsInGroupID(groupID);
-        elementSymbols = createElements(elementIDs);
-    
-        dataMgr.registerTuples(
-            groupID,
-            elementSymbols,
-            
-            new List[] { 
-                Arrays.asList(new Object[] { "a",   new Integer(0),     Boolean.FALSE,  new Double(2.0) }), //$NON-NLS-1$
-                Arrays.asList(new Object[] { null,  new Integer(1),     Boolean.FALSE,  new Double(1.0) }),
-                Arrays.asList(new Object[] { "a",   new Integer(3),     Boolean.TRUE,   new Double(7.0) }), //$NON-NLS-1$
-                Arrays.asList(new Object[] { "c",   new Integer(1),     Boolean.TRUE,   null }), //$NON-NLS-1$
-                Arrays.asList(new Object[] { "b",   new Integer(2),     Boolean.FALSE,  new Double(0.0) }), //$NON-NLS-1$
-                Arrays.asList(new Object[] { "a",   new Integer(0),     Boolean.FALSE,  new Double(2.0) }) //$NON-NLS-1$
-                } );    
-
-        // Group pm2.g3
-        groupID = (FakeMetadataObject) metadata.getGroupID("pm2.g3"); //$NON-NLS-1$
-        elementIDs = metadata.getElementIDsInGroupID(groupID);
-        elementSymbols = createElements(elementIDs);
-    
-        dataMgr.registerTuples(
-            groupID,
-            elementSymbols,
-            
-            new List[] { 
-                Arrays.asList(new Object[] { "a",   new Integer(0),     Boolean.FALSE,  new Double(2.0) }), //$NON-NLS-1$
-                Arrays.asList(new Object[] { null,  new Integer(1),     Boolean.FALSE,  new Double(1.0) }),
-                Arrays.asList(new Object[] { "a",   new Integer(3),     Boolean.TRUE,   new Double(7.0) }), //$NON-NLS-1$
-                Arrays.asList(new Object[] { "c",   new Integer(1),     Boolean.TRUE,   null }), //$NON-NLS-1$
-                Arrays.asList(new Object[] { "b",   new Integer(2),     Boolean.FALSE,  new Double(0.0) }), //$NON-NLS-1$
-                Arrays.asList(new Object[] { "a",   new Integer(0),     Boolean.FALSE,  new Double(2.0) }) //$NON-NLS-1$
-                } );    
-
-        // Group tm1.g1
-        groupID = (FakeMetadataObject) metadata.getGroupID("tm1.g1"); //$NON-NLS-1$
-        elementIDs = metadata.getElementIDsInGroupID(groupID);
-        elementSymbols = createElements(elementIDs);
-    
-        dataMgr.registerTuples(
-            groupID,
-            elementSymbols,
-            
-            new List[] { 
-                Arrays.asList(new Object[] { "a",   new Integer(0),     Boolean.FALSE,  new Double(2.0) }), //$NON-NLS-1$
-                Arrays.asList(new Object[] { null,  new Integer(1),     Boolean.FALSE,  new Double(1.0) }),
-                Arrays.asList(new Object[] { "a",   new Integer(3),     Boolean.TRUE,   new Double(7.0) }), //$NON-NLS-1$
-                Arrays.asList(new Object[] { "c",   new Integer(1),     Boolean.TRUE,   null }), //$NON-NLS-1$
-                Arrays.asList(new Object[] { "b",   new Integer(2),     Boolean.FALSE,  new Double(0.0) }), //$NON-NLS-1$
-                Arrays.asList(new Object[] { "a",   new Integer(0),     Boolean.FALSE,  new Double(2.0) }) //$NON-NLS-1$
-                } );    
-
         //stored procedure pm1.sp1
         TempMetadataStore tempStore = new TempMetadataStore();          
         StoredProcedureInfo procInfo = metadata.getStoredProcedureInfoForProcedure("pm1.sp1"); //$NON-NLS-1$
-        elementSymbols = getProcResultSetSymbols(procInfo.getParameters());
+        List elementSymbols = getProcResultSetSymbols(procInfo.getParameters());
         tempStore.addTempGroup("pm1.sp1", elementSymbols); //$NON-NLS-1$
         Object procID = tempStore.getTempGroupID("pm1.sp1"); //$NON-NLS-1$
         dataMgr.registerTuples(
@@ -225,6 +118,27 @@
                 } );    
     }
 
+	public static void addTable(String name, FakeDataManager dataMgr,
+			QueryMetadataInterface metadata) throws TeiidComponentException,
+			QueryMetadataException {
+		Object groupID = metadata.getGroupID(name);
+        List elementIDs = metadata.getElementIDsInGroupID(groupID);
+        List elementSymbols = createElements(elementIDs, metadata);
+    
+        dataMgr.registerTuples(
+            groupID,
+            elementSymbols,
+            
+            new List[] { 
+                Arrays.asList(new Object[] { "a",   new Integer(0),     Boolean.FALSE,  new Double(2.0) }), //$NON-NLS-1$
+                Arrays.asList(new Object[] { null,  new Integer(1),     Boolean.FALSE,  new Double(1.0) }),
+                Arrays.asList(new Object[] { "a",   new Integer(3),     Boolean.TRUE,   new Double(7.0) }), //$NON-NLS-1$
+                Arrays.asList(new Object[] { "c",   new Integer(1),     Boolean.TRUE,   null }), //$NON-NLS-1$
+                Arrays.asList(new Object[] { "b",   new Integer(2),     Boolean.FALSE,  new Double(0.0) }), //$NON-NLS-1$
+                Arrays.asList(new Object[] { "a",   new Integer(0),     Boolean.FALSE,  new Double(2.0) }) //$NON-NLS-1$
+                } );
+	}
+
     public static void sampleData2(FakeDataManager dataMgr) throws QueryMetadataException, TeiidComponentException {
 		FakeMetadataFacade metadata = FakeMetadataFactory.example1Cached();
 
@@ -232,7 +146,7 @@
 		FakeMetadataObject groupID = (FakeMetadataObject) metadata
 				.getGroupID("pm1.g1"); //$NON-NLS-1$
 		List elementIDs = metadata.getElementIDsInGroupID(groupID);
-		List elementSymbols = createElements(elementIDs);
+		List elementSymbols = createElements(elementIDs, metadata);
 
 		dataMgr.registerTuples(groupID, elementSymbols,
 
@@ -248,7 +162,7 @@
 		// Group pm1.g2
 		groupID = (FakeMetadataObject) metadata.getGroupID("pm1.g2"); //$NON-NLS-1$
 		elementIDs = metadata.getElementIDsInGroupID(groupID);
-		elementSymbols = createElements(elementIDs);
+		elementSymbols = createElements(elementIDs, metadata);
 
 		dataMgr.registerTuples(groupID, elementSymbols,
 
@@ -268,7 +182,7 @@
 		// Group pm2.g1
 		groupID = (FakeMetadataObject) metadata.getGroupID("pm2.g1"); //$NON-NLS-1$
 		elementIDs = metadata.getElementIDsInGroupID(groupID);
-		elementSymbols = createElements(elementIDs);
+		elementSymbols = createElements(elementIDs, metadata);
 
 		dataMgr.registerTuples(groupID, elementSymbols,
 
@@ -284,7 +198,7 @@
 		// Group pm2.g2
 		groupID = (FakeMetadataObject) metadata.getGroupID("pm2.g2"); //$NON-NLS-1$
 		elementIDs = metadata.getElementIDsInGroupID(groupID);
-		elementSymbols = createElements(elementIDs);
+		elementSymbols = createElements(elementIDs, metadata);
 
 		dataMgr.registerTuples(groupID, elementSymbols,
 
@@ -304,7 +218,7 @@
 		// Group pm1.table1
 		groupID = (FakeMetadataObject) metadata.getGroupID("pm1.table1"); //$NON-NLS-1$
 		elementIDs = metadata.getElementIDsInGroupID(groupID);
-		elementSymbols = createElements(elementIDs);
+		elementSymbols = createElements(elementIDs, metadata);
 
 		dataMgr.registerTuples(groupID, elementSymbols,
 

Modified: trunk/engine/src/test/java/org/teiid/query/processor/TestProcessor.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/TestProcessor.java	2010-12-02 15:32:06 UTC (rev 2751)
+++ trunk/engine/src/test/java/org/teiid/query/processor/TestProcessor.java	2010-12-02 21:53:52 UTC (rev 2752)
@@ -353,7 +353,7 @@
     	
     public static void sampleData1(FakeDataManager dataMgr) {
         try { 
-        	FakeDataStore.sampleData1(dataMgr);
+        	FakeDataStore.sampleData1(dataMgr, FakeMetadataFactory.example1Cached());
         } catch(Throwable e) { 
         	throw new RuntimeException(e);
         }

Added: trunk/engine/src/test/java/org/teiid/query/processor/TestTriggerActions.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/TestTriggerActions.java	                        (rev 0)
+++ trunk/engine/src/test/java/org/teiid/query/processor/TestTriggerActions.java	2010-12-02 21:53:52 UTC (rev 2752)
@@ -0,0 +1,124 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.query.processor;
+
+import static org.junit.Assert.*;
+import static org.teiid.query.processor.TestProcessor.*;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.Test;
+import org.teiid.metadata.Table;
+import org.teiid.query.metadata.TransformationMetadata;
+import org.teiid.query.optimizer.TestOptimizer;
+import org.teiid.query.optimizer.capabilities.BasicSourceCapabilities;
+import org.teiid.query.optimizer.capabilities.DefaultCapabilitiesFinder;
+import org.teiid.query.resolver.TestResolver;
+import org.teiid.query.util.CommandContext;
+import org.teiid.query.validator.TestUpdateValidator;
+
+ at SuppressWarnings("nls")
+public class TestTriggerActions {
+    
+	@Test public void testInsert() throws Exception {
+		TransformationMetadata metadata = TestUpdateValidator.example1();
+		TestUpdateValidator.createView("select 1 as x, 2 as y", metadata, "gx");
+		Table t = metadata.getMetadataStore().getSchemas().get("vm1").getTables().get("gx");
+		t.setDeletePlan("");
+		t.setUpdatePlan("");
+		t.setInsertPlan("FOR EACH ROW BEGIN insert into pm1.g1 (e1) values (new.x); END");
+		
+		String sql = "insert into gx (x, y) values (1, 2)";
+		
+		FakeDataManager dm = new FakeDataManager();
+		FakeDataStore.addTable("pm1.g1", dm, metadata);
+		
+		CommandContext context = createCommandContext();
+        BasicSourceCapabilities caps = TestOptimizer.getTypicalCapabilities();
+        ProcessorPlan plan = TestProcessor.helpGetPlan(TestResolver.helpResolve(sql, metadata, null), metadata, new DefaultCapabilitiesFinder(caps), context);
+        List[] expected = new List[] {Arrays.asList(1)};
+    	helpProcess(plan, context, dm, expected);
+	}
+	
+	@Test public void testInsertWithQueryExpression() throws Exception {
+		TransformationMetadata metadata = TestUpdateValidator.example1();
+		TestUpdateValidator.createView("select '1' as x, 2 as y", metadata, "gx");
+		Table t = metadata.getMetadataStore().getSchemas().get("vm1").getTables().get("gx");
+		t.setDeletePlan("");
+		t.setUpdatePlan("");
+		t.setInsertPlan("FOR EACH ROW BEGIN insert into pm1.g1 (e1) values (new.x); END");
+		
+		String sql = "insert into gx (x, y) select e1, e2 from pm1.g1";
+		
+		FakeDataManager dm = new FakeDataManager();
+		FakeDataStore.addTable("pm1.g1", dm, metadata);
+		CommandContext context = createCommandContext();
+        BasicSourceCapabilities caps = TestOptimizer.getTypicalCapabilities();
+        ProcessorPlan plan = TestProcessor.helpGetPlan(TestResolver.helpResolve(sql, metadata, null), metadata, new DefaultCapabilitiesFinder(caps), context);
+        List[] expected = new List[] {Arrays.asList(6)};
+    	helpProcess(plan, context, dm, expected);
+	}
+	
+	@Test public void testDelete() throws Exception {
+		TransformationMetadata metadata = TestUpdateValidator.example1();
+		TestUpdateValidator.createView("select 1 as x, 2 as y", metadata, "gx");
+		Table t = metadata.getMetadataStore().getSchemas().get("vm1").getTables().get("gx");
+		t.setDeletePlan("FOR EACH ROW BEGIN delete from pm1.g1 where e2 = old.x; END");
+		t.setUpdatePlan("");
+		t.setInsertPlan("");
+		
+		String sql = "delete from gx where y = 2";
+		
+		FakeDataManager dm = new FakeDataManager();
+		FakeDataStore.addTable("pm1.g1", dm, metadata);
+		
+		CommandContext context = createCommandContext();
+        BasicSourceCapabilities caps = TestOptimizer.getTypicalCapabilities();
+        ProcessorPlan plan = TestProcessor.helpGetPlan(TestResolver.helpResolve(sql, metadata, null), metadata, new DefaultCapabilitiesFinder(caps), context);
+        List[] expected = new List[] {Arrays.asList(1)};
+    	helpProcess(plan, context, dm, expected);
+	}
+	
+	@Test public void testUpdate() throws Exception {
+		TransformationMetadata metadata = TestUpdateValidator.example1();
+		TestUpdateValidator.createView("select 1 as x, 2 as y", metadata, "gx");
+		Table t = metadata.getMetadataStore().getSchemas().get("vm1").getTables().get("gx");
+		t.setDeletePlan("");
+		t.setUpdatePlan("FOR EACH ROW BEGIN update pm1.g1 set e2 = new.y where e2 = old.y; END");
+		t.setInsertPlan("");
+		
+		String sql = "update gx set y = 5";
+		
+		FakeDataManager dm = new FakeDataManager();
+		FakeDataStore.addTable("pm1.g1", dm, metadata);
+		
+		CommandContext context = createCommandContext();
+        BasicSourceCapabilities caps = TestOptimizer.getTypicalCapabilities();
+        ProcessorPlan plan = TestProcessor.helpGetPlan(TestResolver.helpResolve(sql, metadata, null), metadata, new DefaultCapabilitiesFinder(caps), context);
+        List[] expected = new List[] {Arrays.asList(1)};
+    	helpProcess(plan, context, dm, expected);
+    	assertEquals("UPDATE pm1.g1 SET e2 = 5 WHERE e2 = 2", dm.getQueries().get(0));
+	}
+    
+}


Property changes on: trunk/engine/src/test/java/org/teiid/query/processor/TestTriggerActions.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain



More information about the teiid-commits mailing list