[teiid-commits] teiid SVN: r4475 - in trunk: common-core/src/main/java/org/teiid/core/util and 24 other directories.

teiid-commits at lists.jboss.org teiid-commits at lists.jboss.org
Wed Sep 26 19:16:00 EDT 2012


Author: shawkins
Date: 2012-09-26 19:15:59 -0400 (Wed, 26 Sep 2012)
New Revision: 4475

Modified:
   trunk/build/kits/jboss-as7/docs/teiid/teiid-releasenotes.html
   trunk/common-core/src/main/java/org/teiid/core/util/StringUtil.java
   trunk/engine/src/main/java/org/teiid/query/QueryPlugin.java
   trunk/engine/src/main/java/org/teiid/query/optimizer/ProcedurePlanner.java
   trunk/engine/src/main/java/org/teiid/query/optimizer/QueryOptimizer.java
   trunk/engine/src/main/java/org/teiid/query/optimizer/TriggerActionPlanner.java
   trunk/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java
   trunk/engine/src/main/java/org/teiid/query/processor/proc/CreateCursorResultSetInstruction.java
   trunk/engine/src/main/java/org/teiid/query/processor/proc/ErrorInstruction.java
   trunk/engine/src/main/java/org/teiid/query/processor/proc/ExecDynamicSqlInstruction.java
   trunk/engine/src/main/java/org/teiid/query/processor/proc/IfInstruction.java
   trunk/engine/src/main/java/org/teiid/query/processor/proc/LoopInstruction.java
   trunk/engine/src/main/java/org/teiid/query/processor/proc/ProcedurePlan.java
   trunk/engine/src/main/java/org/teiid/query/processor/proc/Program.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/command/UpdateProcedureResolver.java
   trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
   trunk/engine/src/main/java/org/teiid/query/sql/lang/BatchedUpdateCommand.java
   trunk/engine/src/main/java/org/teiid/query/sql/lang/Command.java
   trunk/engine/src/main/java/org/teiid/query/sql/lang/DynamicCommand.java
   trunk/engine/src/main/java/org/teiid/query/sql/lang/ProcedureContainer.java
   trunk/engine/src/main/java/org/teiid/query/sql/proc/CommandStatement.java
   trunk/engine/src/main/java/org/teiid/query/sql/proc/CreateProcedureCommand.java
   trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java
   trunk/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java
   trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj
   trunk/engine/src/main/resources/org/teiid/query/i18n.properties
   trunk/engine/src/test/java/org/teiid/query/processor/TestTriggerActions.java
   trunk/engine/src/test/java/org/teiid/query/processor/proc/TestProcErrors.java
   trunk/engine/src/test/java/org/teiid/query/processor/proc/TestProcedureProcessor.java
   trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java
   trunk/engine/src/test/java/org/teiid/query/sql/visitor/TestSQLStringVisitor.java
   trunk/engine/src/test/java/org/teiid/query/unittest/RealMetadataFactory.java
   trunk/engine/src/test/java/org/teiid/query/validator/TestAlterValidation.java
   trunk/engine/src/test/java/org/teiid/query/validator/TestValidator.java
   trunk/runtime/src/main/java/org/teiid/runtime/EmbeddedServer.java
   trunk/runtime/src/test/java/org/teiid/runtime/TestEmbeddedServer.java
   trunk/runtime/src/test/java/org/teiid/transport/TestCommSockets.java
   trunk/test-integration/common/src/test/java/org/teiid/jdbc/FakeServer.java
   trunk/test-integration/common/src/test/java/org/teiid/systemmodel/TestMetadataUpdates.java
Log:
TEIID-2226 TEIID-1386 replacing the path logic for result detection and refining exception support

Modified: trunk/build/kits/jboss-as7/docs/teiid/teiid-releasenotes.html
===================================================================
--- trunk/build/kits/jboss-as7/docs/teiid/teiid-releasenotes.html	2012-09-26 17:05:51 UTC (rev 4474)
+++ trunk/build/kits/jboss-as7/docs/teiid/teiid-releasenotes.html	2012-09-26 23:15:59 UTC (rev 4475)
@@ -57,7 +57,9 @@
   <li>TEIID-2187 the CONSTRAINT keyword is not correctly used in table DDL.  It should be replaced with a comma from scripts to be compatible with 8.2.  If desired, 8.2 now supports the CONSTRAINT keyword to provide a name for each constraint.
   <li>TEIID-2181 system tables no longer contain valid OIDs.  That responsibility has moved to the pg_catalog.
   <li>TEIID-1386 the SQLState and errorCode reported by a TeiidSQLException will typically be from the top level nested SQLException.  If there is also a nested TeiidException, the TeiidSQLException.teiidCode will be set to the TeiidException.getCode value and the TeiidSQLException.errorCode will be set
-  to the integer suffix of the teiidCode if possible.  
+  to the integer suffix of the teiidCode if possible.
+  <li>TEIID-2226 All statements that return result sets that are executed as command statements in a procedure are validated against the expected resultset columns of the procedure.
+      If the statement is not intended to be returnable, WITHOUT RETURN can be added to the end of the statement.
 </ul>
 
 <h4>from 8.0</h4>

Modified: trunk/common-core/src/main/java/org/teiid/core/util/StringUtil.java
===================================================================
--- trunk/common-core/src/main/java/org/teiid/core/util/StringUtil.java	2012-09-26 17:05:51 UTC (rev 4474)
+++ trunk/common-core/src/main/java/org/teiid/core/util/StringUtil.java	2012-09-26 23:15:59 UTC (rev 4475)
@@ -74,18 +74,34 @@
      */
     public static final String LINE_SEPARATOR = System.getProperty(LINE_SEPARATOR_PROPERTY_NAME, Constants.NEW_LINE);
 
-    public static final Comparator CASE_INSENSITIVE_ORDER = String.CASE_INSENSITIVE_ORDER;
+    public static final Comparator<String> CASE_INSENSITIVE_ORDER = String.CASE_INSENSITIVE_ORDER;
+    
+    public static final Comparator<String> NULL_SAFE_CASE_INSENSITIVE_ORDER = new Comparator<String>() {
+		@Override
+		public int compare(String o1, String o2) {
+			if (o1 == null) {
+				if (o2 == null) {
+					return 0;
+				}
+				return -1;
+			}
+			if (o2 == null) {
+				return 1;
+			}
+			return String.CASE_INSENSITIVE_ORDER.compare(o1, o2);
+		}
+	};
 
-    public static final Comparator CASE_SENSITIVE_ORDER = new Comparator() {
+    public static final Comparator<String> CASE_SENSITIVE_ORDER = new Comparator<String>() {
         /** 
          * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
          * @since 4.2
          */
-        public int compare(Object o1, Object o2) {
+        public int compare(String o1, String o2) {
             if ( o1 == o2 ) {
                 return 0;
             }
-            return ((String)o1).compareTo((String)o2);
+            return o1.compareTo(o2);
         }
     };
     

Modified: trunk/engine/src/main/java/org/teiid/query/QueryPlugin.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/QueryPlugin.java	2012-09-26 17:05:51 UTC (rev 4474)
+++ trunk/engine/src/main/java/org/teiid/query/QueryPlugin.java	2012-09-26 23:15:59 UTC (rev 4475)
@@ -330,7 +330,6 @@
 		TEIID30364,
 		TEIID30365,
 		TEIID30366,
-		TEIID30367,
 		TEIID30371,
 		TEIID30372,
 		TEIID30373,
@@ -535,6 +534,7 @@
     	TEIID31118,
     	TEIID31119, 
     	TEIID31120, 
-    	TEIID31121,
+    	TEIID31121, 
+    	TEIID31122,
 	}
 }

Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/ProcedurePlanner.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/ProcedurePlanner.java	2012-09-26 17:05:51 UTC (rev 4474)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/ProcedurePlanner.java	2012-09-26 23:15:59 UTC (rev 4475)
@@ -36,6 +36,7 @@
 import org.teiid.query.optimizer.capabilities.CapabilitiesFinder;
 import org.teiid.query.processor.ProcessorPlan;
 import org.teiid.query.processor.proc.*;
+import org.teiid.query.processor.proc.CreateCursorResultSetInstruction.Mode;
 import org.teiid.query.sql.lang.Command;
 import org.teiid.query.sql.lang.DynamicCommand;
 import org.teiid.query.sql.lang.SPParameter;
@@ -97,7 +98,7 @@
                 
         // create plan from program and initialized environment
         ProcedurePlan plan = new ProcedurePlan(programBlock);
-        
+        plan.setMetadata(metadata);
         plan.setOutputElements(cupc.getProjectedSymbols());
         
         if(debug) {
@@ -231,12 +232,9 @@
 				ProcessorPlan commandPlan = cmdStmt.getCommand().getProcessorPlan();                
                 
 				if (command.getType() == Command.TYPE_DYNAMIC){
-					instruction = new ExecDynamicSqlInstruction(parentProcCommand,((DynamicCommand)command), metadata, idGenerator, capFinder );
+					instruction = new ExecDynamicSqlInstruction(parentProcCommand,((DynamicCommand)command), metadata, idGenerator, capFinder, cmdStmt.isReturnable() );
 				}else{
-					instruction = new CreateCursorResultSetInstruction(CreateCursorResultSetInstruction.RS_NAME, commandPlan, 
-							command.getType() == Command.TYPE_INSERT 
-							|| command.getType() == Command.TYPE_UPDATE
-							|| command.getType() == Command.TYPE_DELETE);
+					instruction = new CreateCursorResultSetInstruction(null, commandPlan, (!command.returnsResultSet()&&!(command instanceof StoredProcedure))?Mode.UPDATE:(cmdStmt.isReturnable()&&cmdStmt.getCommand().returnsResultSet())?Mode.HOLD:Mode.NOHOLD);
 					//handle stored procedure calls
 					if (command.getType() == Command.TYPE_STORED_PROCEDURE) {
 						StoredProcedure sp = (StoredProcedure)command;

Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/QueryOptimizer.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/QueryOptimizer.java	2012-09-26 17:05:51 UTC (rev 4474)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/QueryOptimizer.java	2012-09-26 23:15:59 UTC (rev 4475)
@@ -22,9 +22,6 @@
 
 package org.teiid.query.optimizer;
 
-import java.util.LinkedList;
-import java.util.List;
-
 import org.teiid.api.exception.query.QueryMetadataException;
 import org.teiid.api.exception.query.QueryPlannerException;
 import org.teiid.api.exception.query.QueryResolverException;
@@ -40,21 +37,17 @@
 import org.teiid.query.metadata.QueryMetadataInterface;
 import org.teiid.query.metadata.TempCapabilitiesFinder;
 import org.teiid.query.metadata.TempMetadataAdapter;
+import org.teiid.query.metadata.TempMetadataID;
 import org.teiid.query.metadata.TempMetadataStore;
 import org.teiid.query.optimizer.capabilities.CapabilitiesFinder;
 import org.teiid.query.optimizer.relational.RelationalPlanner;
 import org.teiid.query.optimizer.xml.XMLPlanner;
 import org.teiid.query.processor.ProcessorPlan;
-import org.teiid.query.processor.proc.ProcedurePlan;
 import org.teiid.query.resolver.QueryResolver;
 import org.teiid.query.rewriter.QueryRewriter;
 import org.teiid.query.sql.lang.Command;
-import org.teiid.query.sql.lang.ProcedureContainer;
 import org.teiid.query.sql.lang.Query;
-import org.teiid.query.sql.lang.SPParameter;
-import org.teiid.query.sql.lang.StoredProcedure;
 import org.teiid.query.sql.proc.CreateProcedureCommand;
-import org.teiid.query.sql.symbol.ElementSymbol;
 import org.teiid.query.util.CommandContext;
 
 
@@ -111,14 +104,16 @@
 		switch (command.getType()) {
 		case Command.TYPE_UPDATE_PROCEDURE:
 			CreateProcedureCommand cupc = (CreateProcedureCommand)command;
-			if (cupc.getUserCommand() == null) {
+			if (cupc.getUpdateType() != Command.TYPE_UNKNOWN) {
 				//row update procedure
 				result = planProcedure(command, metadata, idGenerator, capFinder, analysisRecord, context);
 			} else {
-				StoredProcedure c = (StoredProcedure)cupc.getUserCommand();
 				Object pid = cupc.getVirtualGroup().getMetadataID();
-				if (c != null) {
-					pid = c.getProcedureID();
+				if (pid instanceof TempMetadataID) {
+					TempMetadataID tid = (TempMetadataID)pid;
+					if (tid.getOriginalMetadataID() != null) {
+						pid = tid.getOriginalMetadataID();
+					}
 				}
 				String fullName = metadata.getFullName(pid);
 				fullName = "procedure cache:" + fullName; //$NON-NLS-1$
@@ -141,34 +136,6 @@
 					context.accessedPlanningObject(id);
 				}
 			}
-	        // propagate procedure parameters to the plan to allow runtime type checking
-	        ProcedureContainer container = (ProcedureContainer)cupc.getUserCommand();
-	        ProcedurePlan plan = (ProcedurePlan)result;
-	        if (container != null) {
-	        	if (container instanceof StoredProcedure) {
-	        		plan.setRequiresTransaction(container.getUpdateCount() > 0);
-	        		StoredProcedure sp = (StoredProcedure)container;
-	        		if (sp.returnParameters()) {
-	        			List<ElementSymbol> outParams = new LinkedList<ElementSymbol>();
-	        			for (SPParameter param : sp.getParameters()) {
-							if (param.getParameterType() == SPParameter.RETURN_VALUE) {
-								outParams.add(param.getParameterSymbol());
-							}
-						}
-	        			for (SPParameter param : sp.getParameters()) {
-							if (param.getParameterType() == SPParameter.INOUT || 
-									param.getParameterType() == SPParameter.OUT) {
-								outParams.add(param.getParameterSymbol());
-							}
-						}
-	        			if (outParams.size() > 0) {
-	        				plan.setOutParams(outParams);
-	        			}
-	        		}
-	        		plan.setParams(sp.getProcedureParameters());
-	        	}
-	            plan.setMetadata(metadata);
-	        }
 	        break;
 		case Command.TYPE_BATCHED_UPDATE:
 			result = BATCHED_UPDATE_PLANNER.optimize(command, idGenerator, metadata, capFinder, analysisRecord, context);

Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/TriggerActionPlanner.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/TriggerActionPlanner.java	2012-09-26 17:05:51 UTC (rev 4474)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/TriggerActionPlanner.java	2012-09-26 23:15:59 UTC (rev 4475)
@@ -99,7 +99,7 @@
 		result.setLookupMap(RelationalNode.createLookupMap(query.getProjectedSymbols()));
 		CreateProcedureCommand command = new CreateProcedureCommand(ta.getBlock());
 		command.setVirtualGroup(ta.getView());
-		command.setUpdateType(userCommand.getClass().getSimpleName());
+		command.setUpdateType(userCommand.getType());
 		ProcedurePlan rowProcedure = (ProcedurePlan)QueryOptimizer.optimizePlan(command, metadata, idGenerator, capFinder, analysisRecord, context);
 		result.setRowProcedure(rowProcedure);
 		return result;

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	2012-09-26 17:05:51 UTC (rev 4474)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java	2012-09-26 23:15:59 UTC (rev 4475)
@@ -61,6 +61,7 @@
 import org.teiid.query.optimizer.relational.rules.RulePlaceAccess;
 import org.teiid.query.optimizer.relational.rules.RulePushAggregates;
 import org.teiid.query.processor.ProcessorPlan;
+import org.teiid.query.processor.proc.ProcedurePlan;
 import org.teiid.query.processor.relational.AccessNode;
 import org.teiid.query.processor.relational.RelationalPlan;
 import org.teiid.query.processor.relational.JoinNode.JoinStrategyType;
@@ -581,13 +582,18 @@
 		if (c == null) {
 			c = QueryResolver.expandCommand(container, metadata, analysisRecord);
 			if (c != null) {
+				if (c instanceof CreateProcedureCommand) {
+					//TODO: find a better way to do this
+					((CreateProcedureCommand)c).setProjectedSymbols(container.getProjectedSymbols());
+				}
 		        Request.validateWithVisitor(new ValidationVisitor(), metadata, c);
 		        metadata.addToMetadataCache(metadataId, cacheString, c.clone());
 			}
 		} else {
 			c = (Command)c.clone();
 			if (c instanceof CreateProcedureCommand) {
-				((CreateProcedureCommand)c).setUserCommand(container);
+				//TODO: find a better way to do this
+				((CreateProcedureCommand)c).setProjectedSymbols(container.getProjectedSymbols());
 			}
 		}
 		if (c != null) {
@@ -1007,6 +1013,30 @@
 				actualMetadata = ((TempMetadataAdapter)metadata).getMetadata();
 			}
 			ProcessorPlan plan = QueryOptimizer.optimizePlan(toPlan, actualMetadata, idGenerator, capFinder, analysisRecord, context);
+			//hack for the optimizer not knowing the containing command when forming the plan
+			if (nestedCommand instanceof StoredProcedure && plan instanceof ProcedurePlan) {
+				StoredProcedure container = (StoredProcedure)nestedCommand;
+				ProcedurePlan pp = (ProcedurePlan)plan;
+				pp.setRequiresTransaction(container.getUpdateCount() > 0);
+        		if (container.returnParameters()) {
+        			List<ElementSymbol> outParams = new LinkedList<ElementSymbol>();
+        			for (SPParameter param : container.getParameters()) {
+						if (param.getParameterType() == SPParameter.RETURN_VALUE) {
+							outParams.add(param.getParameterSymbol());
+						}
+					}
+        			for (SPParameter param : container.getParameters()) {
+						if (param.getParameterType() == SPParameter.INOUT || 
+								param.getParameterType() == SPParameter.OUT) {
+							outParams.add(param.getParameterSymbol());
+						}
+					}
+        			if (outParams.size() > 0) {
+        				pp.setOutParams(outParams);
+        			}
+        		}
+        		pp.setParams(container.getProcedureParameters());
+			}
 		    node.setProperty(NodeConstants.Info.PROCESSOR_PLAN, plan);
 		}
 	}

Modified: trunk/engine/src/main/java/org/teiid/query/processor/proc/CreateCursorResultSetInstruction.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/proc/CreateCursorResultSetInstruction.java	2012-09-26 17:05:51 UTC (rev 4474)
+++ trunk/engine/src/main/java/org/teiid/query/processor/proc/CreateCursorResultSetInstruction.java	2012-09-26 23:15:59 UTC (rev 4475)
@@ -40,17 +40,21 @@
  */
 public class CreateCursorResultSetInstruction extends ProgramInstruction {
 	
-	public static final String RS_NAME = "EXECSQL_INSTRUCTION"; //$NON-NLS-1$
+	public enum Mode {
+		UPDATE,
+		HOLD,
+		NOHOLD
+	}
 	
     protected String rsName;
     protected ProcessorPlan plan;
-    private boolean update;
+    private Mode mode;
     private Map<ElementSymbol, ElementSymbol> procAssignments;
     
-    public CreateCursorResultSetInstruction(String rsName, ProcessorPlan plan, boolean update){
+    public CreateCursorResultSetInstruction(String rsName, ProcessorPlan plan, Mode mode){
         this.rsName = rsName;
         this.plan = plan;
-        this.update = update;
+        this.mode = mode;
     }
     
     public void setProcAssignments(
@@ -60,22 +64,8 @@
     
     public void process(ProcedurePlan procEnv)
         throws BlockedException, TeiidComponentException, TeiidProcessingException {
-
-        if(procEnv.resultSetExists(rsName)) {
-            procEnv.removeResults(rsName);
-        }
-        
-        procEnv.executePlan(plan, rsName, procAssignments, !update);
-        
-        if (update) {
-        	boolean hasNext = procEnv.iterateCursor(rsName);
-    		if (hasNext) {
-    			procEnv.getCurrentVariableContext().setValue(ProcedurePlan.ROWCOUNT, procEnv.getCurrentRow(rsName).get(0));
-    		} else {
-    			procEnv.getCurrentVariableContext().setValue(ProcedurePlan.ROWCOUNT, 0);
-    		}
-    		procEnv.removeResults(rsName);
-        }
+    	
+        procEnv.executePlan(plan, rsName, procAssignments, mode);
     }
 
     /**
@@ -83,7 +73,7 @@
      */
     public CreateCursorResultSetInstruction clone(){
         ProcessorPlan clonedPlan = this.plan.clone();
-        CreateCursorResultSetInstruction clone = new CreateCursorResultSetInstruction(this.rsName, clonedPlan, update);
+        CreateCursorResultSetInstruction clone = new CreateCursorResultSetInstruction(this.rsName, clonedPlan, mode);
         clone.setProcAssignments(procAssignments);
         return clone;
     }

Modified: trunk/engine/src/main/java/org/teiid/query/processor/proc/ErrorInstruction.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/proc/ErrorInstruction.java	2012-09-26 17:05:51 UTC (rev 4474)
+++ trunk/engine/src/main/java/org/teiid/query/processor/proc/ErrorInstruction.java	2012-09-26 23:15:59 UTC (rev 4475)
@@ -29,6 +29,7 @@
 import org.teiid.core.TeiidProcessingException;
 import org.teiid.jdbc.TeiidSQLException;
 import org.teiid.logging.LogManager;
+import org.teiid.query.QueryPlugin;
 import org.teiid.query.sql.symbol.Expression;
 
 
@@ -85,7 +86,7 @@
         	return;
         }
         if (value == null) {
-        	throw new TeiidProcessingException();
+        	throw new TeiidProcessingException(QueryPlugin.Event.TEIID31122, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31122));
         }
         throw TeiidSQLException.create((Exception)value);
     }

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	2012-09-26 17:05:51 UTC (rev 4474)
+++ trunk/engine/src/main/java/org/teiid/query/processor/proc/ExecDynamicSqlInstruction.java	2012-09-26 23:15:59 UTC (rev 4475)
@@ -52,6 +52,7 @@
 import org.teiid.query.parser.QueryParser;
 import org.teiid.query.processor.ProcessorPlan;
 import org.teiid.query.processor.RegisterRequestParameter;
+import org.teiid.query.processor.proc.CreateCursorResultSetInstruction.Mode;
 import org.teiid.query.resolver.QueryResolver;
 import org.teiid.query.rewriter.QueryRewriter;
 import org.teiid.query.sql.ProcedureReservedWords;
@@ -92,6 +93,7 @@
 
 	// the metadata for this plan
 	private QueryMetadataInterface metadata;
+	private boolean returnable;
 
 	// The parent command
 	CreateProcedureCommand parentProcCommand;
@@ -101,12 +103,13 @@
 	public ExecDynamicSqlInstruction(
 			CreateProcedureCommand parentProcCommand,
 			DynamicCommand command, QueryMetadataInterface metadata,
-			IDGenerator idGenerator, CapabilitiesFinder capFinder) {
+			IDGenerator idGenerator, CapabilitiesFinder capFinder, boolean returnable) {
 		this.parentProcCommand = parentProcCommand;
 		this.dynamicCommand = command;
 		this.metadata = metadata;
 		this.capFinder = capFinder;
 		this.idGenerator = idGenerator;
+		this.returnable = returnable;
 	}
 
 	/**
@@ -185,7 +188,7 @@
 							.createNonRecordingRecord(), procEnv
 							.getContext());
             
-			CreateCursorResultSetInstruction inst = new CreateCursorResultSetInstruction(CreateCursorResultSetInstruction.RS_NAME, commandPlan, dynamicCommand.getIntoGroup() != null) {
+			CreateCursorResultSetInstruction inst = new CreateCursorResultSetInstruction(null, commandPlan, dynamicCommand.getIntoGroup() != null?Mode.UPDATE:returnable?Mode.HOLD:Mode.NOHOLD) {
 				@Override
 				public void process(ProcedurePlan procEnv)
 						throws BlockedException, TeiidComponentException,
@@ -316,8 +319,8 @@
 		// do a recursion check
 		// Add group to recursion stack
 		CommandContext context = procEnv.getContext();
-		if (parentProcCommand.getUpdateType() != null) {
-			context.pushCall(parentProcCommand.getUpdateType() + " " + parentProcCommand.getVirtualGroup()); //$NON-NLS-1$
+		if (parentProcCommand.getUpdateType() != Command.TYPE_UNKNOWN) {
+			context.pushCall(Command.getCommandToken(parentProcCommand.getUpdateType()) + " " + parentProcCommand.getVirtualGroup()); //$NON-NLS-1$
 		} else {
 			context.pushCall(parentProcCommand.getVirtualGroup().toString());
 		}
@@ -328,7 +331,7 @@
 	 */
 	public ExecDynamicSqlInstruction clone() {
 		ExecDynamicSqlInstruction clone = new ExecDynamicSqlInstruction(
-				parentProcCommand, dynamicCommand, metadata, idGenerator, capFinder);
+				parentProcCommand, dynamicCommand, metadata, idGenerator, capFinder, returnable);
 		return clone;
 	}
 
@@ -341,5 +344,13 @@
 		props.addProperty(PROP_SQL, dynamicCommand.toString()); 
 		return props;
 	}
+	
+	public boolean isReturnable() {
+		return returnable;
+	}
+	
+	public void setReturnable(boolean returnable) {
+		this.returnable = returnable;
+	}
 
 }

Modified: trunk/engine/src/main/java/org/teiid/query/processor/proc/IfInstruction.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/proc/IfInstruction.java	2012-09-26 17:05:51 UTC (rev 4474)
+++ trunk/engine/src/main/java/org/teiid/query/processor/proc/IfInstruction.java	2012-09-26 23:15:59 UTC (rev 4475)
@@ -125,7 +125,14 @@
     }
 
     public String toString() {
-        return "IF INSTRUCTION:"; //$NON-NLS-1$
+    	StringBuffer sb = new StringBuffer("IF INSTRUCTION: "); //$NON-NLS-1$
+    	sb.append(condition);
+    	sb.append("\n").append(ifProgram); //$NON-NLS-1$
+    	if (elseProgram!=null) {
+    		sb.append("\nELSE\n"); //$NON-NLS-1$
+    		sb.append(elseProgram);
+    	}
+    	return sb.toString();
     }
 
     public PlanNode getDescriptionProperties() {

Modified: trunk/engine/src/main/java/org/teiid/query/processor/proc/LoopInstruction.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/proc/LoopInstruction.java	2012-09-26 17:05:51 UTC (rev 4474)
+++ trunk/engine/src/main/java/org/teiid/query/processor/proc/LoopInstruction.java	2012-09-26 23:15:59 UTC (rev 4475)
@@ -49,7 +49,7 @@
     private String label;
     
     public LoopInstruction(Program loopProgram, String rsName, ProcessorPlan plan, String label) {
-        super(rsName, plan, false);
+        super(rsName, plan, Mode.NOHOLD);
         this.loopProgram = loopProgram;
         this.label = label;
     }
@@ -105,7 +105,7 @@
 
     public boolean testCondition(ProcedurePlan procEnv) throws TeiidComponentException, TeiidProcessingException {
         if(!procEnv.resultSetExists(rsName)) {
-            procEnv.executePlan(plan, rsName, null, false);            
+            procEnv.executePlan(plan, rsName, null, Mode.NOHOLD);            
         }
         
         return procEnv.iterateCursor(rsName);

Modified: trunk/engine/src/main/java/org/teiid/query/processor/proc/ProcedurePlan.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/proc/ProcedurePlan.java	2012-09-26 17:05:51 UTC (rev 4474)
+++ trunk/engine/src/main/java/org/teiid/query/processor/proc/ProcedurePlan.java	2012-09-26 23:15:59 UTC (rev 4475)
@@ -28,12 +28,12 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Stack;
+import java.util.TreeMap;
 
 import org.teiid.api.exception.query.QueryMetadataException;
 import org.teiid.api.exception.query.QueryValidatorException;
@@ -52,6 +52,7 @@
 import org.teiid.core.types.ArrayImpl;
 import org.teiid.core.types.DataTypeManager;
 import org.teiid.core.util.Assertion;
+import org.teiid.core.util.StringUtil;
 import org.teiid.dqp.internal.process.DataTierTupleSource;
 import org.teiid.dqp.service.TransactionContext;
 import org.teiid.dqp.service.TransactionService;
@@ -70,6 +71,7 @@
 import org.teiid.query.processor.ProcessorPlan;
 import org.teiid.query.processor.QueryProcessor;
 import org.teiid.query.processor.RegisterRequestParameter;
+import org.teiid.query.processor.proc.CreateCursorResultSetInstruction.Mode;
 import org.teiid.query.processor.relational.SubqueryAwareEvaluator;
 import org.teiid.query.resolver.command.UpdateProcedureResolver;
 import org.teiid.query.sql.ProcedureReservedWords;
@@ -93,6 +95,13 @@
 		TupleBuffer resultsBuffer;
 	}
 	
+	static ElementSymbol ROWCOUNT =
+		new ElementSymbol(ProcedureReservedWords.VARIABLES+"."+ProcedureReservedWords.ROWCOUNT); //$NON-NLS-1$
+	
+	static {
+		ROWCOUNT.setType(DataTypeManager.DefaultDataClasses.INTEGER);
+	}
+	
     private Program originalProgram;
 
 	// State initialized by processor
@@ -113,18 +122,11 @@
     private List<ElementSymbol> outParams;
     private QueryMetadataInterface metadata;
 
-    private Map<String, CursorState> cursorStates = new HashMap<String, CursorState>();
+    private Map<String, CursorState> cursorStates = new TreeMap<String, CursorState>(StringUtil.NULL_SAFE_CASE_INSENSITIVE_ORDER);
 
-	static ElementSymbol ROWCOUNT =
-		new ElementSymbol(ProcedureReservedWords.VARIABLES+"."+ProcedureReservedWords.ROWCOUNT); //$NON-NLS-1$
-	
-	static {
-		ROWCOUNT.setType(DataTypeManager.DefaultDataClasses.INTEGER);
-	}
-
 	private VariableContext currentVarContext;
 
-    private TupleSource lastTupleSource;
+    private CursorState last;
     
     private List outputElements;
     
@@ -202,11 +204,10 @@
         evaluatedParams = false;
         cursorStates.clear();
         createVariableContext();
-        lastTupleSource = null;
+        last = null;
         
         done = false;
         currentState = null;
-
         finalTupleSource = null;
         beginBatch = 1;
         batchRows = null;
@@ -377,20 +378,16 @@
 	            	LogManager.logTrace(org.teiid.logging.LogConstants.CTX_DQP, "Executing instruction", inst); //$NON-NLS-1$
 	                inst.process(this);
 	            }
+	        } catch (RuntimeException e) {
+	        	throw e;
+	        } catch (TeiidComponentException e) {
+	        	throw e;
 	        } catch (Exception e) {
-	        	if (e instanceof BlockedException) {
-	        		throw (BlockedException)e;
-	        	}
+	        	//processing or teiidsqlexception
 	        	while (program.getExceptionGroup() == null) {
         			this.pop(false);
 	        		if (this.programs.empty()) {
 	        			//reached the top without a handler, so throw
-        				if (e instanceof RuntimeException) {
-    	        			throw (RuntimeException)e;
-    	        		}
-    	        		if (e instanceof TeiidComponentException) {
-    	        			throw (TeiidComponentException)e;
-    	        		}
     	        		if (e instanceof TeiidProcessingException) {
     	        			throw (TeiidProcessingException)e;
     	        		}
@@ -398,7 +395,6 @@
 	        		}
         			program = peek();
 	        	}
-        		//assign variables
         		if (program.getExceptionProgram() == null) {
         			this.pop(true);
         			continue;
@@ -419,10 +415,10 @@
             program.incrementProgramCounter();
 	    }
 
-        if(lastTupleSource == null){
+        if(last == null){
             return CollectionTupleSource.createNullTupleSource();
         }
-        return lastTupleSource;
+        return last.ts;
     }
 
 	private ElementSymbol exceptionSymbol(GroupSymbol gs, int pos) {
@@ -543,11 +539,16 @@
 		return this.currentVarContext;
     }
 
-    public void executePlan(ProcessorPlan command, String rsName, Map<ElementSymbol, ElementSymbol> procAssignments, boolean keepRs)
+    public void executePlan(ProcessorPlan command, String rsName, Map<ElementSymbol, ElementSymbol> procAssignments, CreateCursorResultSetInstruction.Mode mode)
         throws TeiidComponentException, TeiidProcessingException {
     	
-        CursorState state = this.cursorStates.get(rsName.toUpperCase());
+        CursorState state = this.cursorStates.get(rsName);
         if (state == null) {
+        	if (this.currentState != null && this.currentState.processor.getProcessorPlan() != command) {
+        		//sanity check for non-deterministic paths
+        		removeState(this.currentState);
+        		this.currentState = null;
+        	}
         	if (this.currentState == null) {
 		        //this may not be the first time the plan is being run
 		        command.reset();
@@ -557,16 +558,17 @@
 		        state = new CursorState();
 		        state.processor = new QueryProcessor(command, subContext, this.bufferMgr, this.dataMgr);
 		        state.ts = new BatchIterator(state.processor);
-		        if (procAssignments != null && state.processor.getOutputElements().size() - procAssignments.size() > 0) {
+		        if (mode == Mode.HOLD && procAssignments != null && state.processor.getOutputElements().size() - procAssignments.size() > 0) {
 		        	state.resultsBuffer = bufferMgr.createTupleBuffer(state.processor.getOutputElements().subList(0, state.processor.getOutputElements().size() - procAssignments.size()), getContext().getConnectionId(), TupleSourceType.PROCESSOR);
-		        } else if (this.blockContext != null) {
+		        } else if ((this.blockContext != null || this.programs.peek().isTrappingExceptions()) && (mode == Mode.HOLD || rsName != null)) {
 		        	state.resultsBuffer = bufferMgr.createTupleBuffer(state.processor.getOutputElements(), getContext().getConnectionId(), TupleSourceType.PROCESSOR);
 		        }
 	            this.currentState = state;
         	}
-        	//force execution to the first batch
+        	//force execution to the first batch to ensure that the plan is executed in the context of the procedure
         	this.currentState.ts.hasNext();
         	if (procAssignments != null) {
+        		//proc assignments force us to scroll through the entire results and save as we go
             	while (this.currentState.ts.hasNext()) {
             		if (this.currentState.currentRow != null && this.currentState.resultsBuffer != null) {
             			this.currentState.resultsBuffer.addTuple(this.currentState.currentRow.subList(0, this.currentState.resultsBuffer.getSchema().size()));
@@ -583,28 +585,49 @@
             		int index = this.currentState.processor.getOutputElements().indexOf(entry.getKey());
             		getCurrentVariableContext().setValue(entry.getValue(), DataTypeManager.transformValue(this.currentState.currentRow.get(index), entry.getValue().getType()));
 				}
-            	//no resultset
-            	if (this.currentState.resultsBuffer == null) {
-            		this.currentState.processor.closeProcessing();
-            		this.currentState = null;
-            		return;
-            	}
-            	this.currentState.resultsBuffer.close();
-            	this.currentState.ts = this.currentState.resultsBuffer.createIndexedTupleSource();
-            } else if (this.blockContext != null) {
-            	//process fully in a block transaction
+            } else if (this.currentState.resultsBuffer != null) {
+            	//result should be saved, typically to respect txn semantics
             	while (this.currentState.ts.hasNext()) {
             		List<?> tuple = this.currentState.ts.nextTuple();
         			this.currentState.resultsBuffer.addTuple(tuple);
+            	}	
+            } else if (mode == Mode.UPDATE) {
+        		List<?> t = this.currentState.ts.nextTuple();
+        		if (this.currentState.ts.hasNext()) {
+        			throw new AssertionError("Invalid update count result - more than 1 row returned"); //$NON-NLS-1$
+        		}
+        		removeState(this.currentState);
+        		this.currentState = null;
+        		int rowCount = 0;
+        		if (t != null) {
+        			rowCount = (Integer)t.get(0);
+        		}
+        		getCurrentVariableContext().setValue(ProcedurePlan.ROWCOUNT, rowCount);
+        		return;
+        	} 
+        	if (rsName == null && mode == Mode.NOHOLD) {
+        		//unnamed without hold
+        		//process fully, but don't save
+            	//TODO: could set the rowcount in this case
+            	while (this.currentState.ts.hasNext()) {
+            		this.currentState.ts.nextTuple();
             	}
+            	this.currentState = null;
+            	return;
+        	}
+        	if (this.currentState.resultsBuffer != null) {
+            	//close the results buffer and use a buffer backed tuplesource
             	this.currentState.resultsBuffer.close();
-            	this.currentState.ts = this.currentState.resultsBuffer.createIndexedTupleSource();
-            }
-	        this.cursorStates.put(rsName.toUpperCase(), this.currentState);
+            	this.currentState.ts = this.currentState.resultsBuffer.createIndexedTupleSource(true);
+        	}
+	        CursorState old = this.cursorStates.put(rsName, this.currentState);
+	        if (old != null) {
+	        	removeState(old);
+	        }
 	        //keep a reference to the tuple source
             //it may be the last one
-	        if (keepRs) {
-	        	this.lastTupleSource = this.currentState.ts;
+	        if (mode == Mode.HOLD) {
+	        	this.last = this.currentState;
 	        }
 	        this.currentState = null;
         }
@@ -647,6 +670,7 @@
     
     public void push(Program program) throws XATransactionException {
     	program.reset(this.getContext().getConnectionId());
+		program.setTrappingExceptions(program.getExceptionGroup() != null || (!this.programs.isEmpty() && this.programs.peek().isTrappingExceptions()));
     	TempTableStore tts = getTempTableStore();
 		getContext().setTempTableStore(program.getTempTableStore());
 		program.getTempTableStore().setParentTempTableStore(tts);
@@ -680,15 +704,13 @@
     }
 
     public List<?> getCurrentRow(String rsName) throws TeiidComponentException {
-        return getCursorState(rsName.toUpperCase()).currentRow;
+        return getCursorState(rsName).currentRow;
     }
 
     public boolean iterateCursor(String rsName)
         throws TeiidComponentException, TeiidProcessingException {
 
-        String rsKey = rsName.toUpperCase();
-
-        CursorState state = getCursorState(rsKey);
+        CursorState state = getCursorState(rsName);
         
         state.currentRow = state.ts.nextTuple();
         return (state.currentRow != null);
@@ -703,15 +725,21 @@
 	}
 
     public void removeResults(String rsName) {
-        String rsKey = rsName.toUpperCase();
-        CursorState state = this.cursorStates.remove(rsKey);
-        if (state != null) {
+		CursorState state = this.cursorStates.remove(rsName);
+        removeState(state);
+    }
+
+	private void removeState(CursorState state) {
+		if (state != null) {
         	state.processor.closeProcessing();
         	if (state.resultsBuffer != null) {
         		state.resultsBuffer.remove();
         	}
         }
-    }
+        if (state == last) {
+        	last = null;
+        }
+	}
 
     /**
      * Get the schema from the tuple source that
@@ -721,20 +749,14 @@
      * @throws QueryProcessorException if the list of elements is null
      */
     public List getSchema(String rsName) throws TeiidComponentException {
-
-        // get the tuple source
-        String rsKey = rsName.toUpperCase();
-        
-        CursorState cursorState = getCursorState(rsKey);
+        CursorState cursorState = getCursorState(rsName);
         // get the schema from the tuple source
         List schema = cursorState.processor.getOutputElements();
         return schema;
     }
 
     public boolean resultSetExists(String rsName) {
-        String rsKey = rsName.toUpperCase();
-        boolean exists = this.cursorStates.containsKey(rsKey);
-        return exists;
+        return this.cursorStates.containsKey(rsName);
     }
 
     public CommandContext getContext() {

Modified: trunk/engine/src/main/java/org/teiid/query/processor/proc/Program.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/proc/Program.java	2012-09-26 17:05:51 UTC (rev 4474)
+++ trunk/engine/src/main/java/org/teiid/query/processor/proc/Program.java	2012-09-26 23:15:59 UTC (rev 4475)
@@ -46,6 +46,7 @@
     private boolean startedTxn;
     private String exceptionGroup;
     private Program exceptionProgram;
+    private boolean trappingExceptions = false;
 
 	/**
 	 * Constructor for Program.
@@ -117,6 +118,7 @@
         counter = 0;
         this.tempTables = new TempTableStore(sessionId, TransactionMode.ISOLATE_WRITES);
         this.startedTxn = false;
+        this.trappingExceptions = false;
     }
 
     int getProgramCounter(){
@@ -283,5 +285,13 @@
 	public Program getExceptionProgram() {
 		return exceptionProgram;
 	}
+	
+	public boolean isTrappingExceptions() {
+		return trappingExceptions;
+	}
+	
+	public void setTrappingExceptions(boolean trappingExceptions) {
+		this.trappingExceptions = trappingExceptions;
+	}
         
 }

Modified: trunk/engine/src/main/java/org/teiid/query/resolver/ProcedureContainerResolver.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/resolver/ProcedureContainerResolver.java	2012-09-26 17:05:51 UTC (rev 4474)
+++ trunk/engine/src/main/java/org/teiid/query/resolver/ProcedureContainerResolver.java	2012-09-26 23:15:59 UTC (rev 4475)
@@ -24,6 +24,7 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 
 import org.teiid.api.exception.query.QueryMetadataException;
@@ -270,7 +271,6 @@
 		} else if (currentCommand instanceof CreateProcedureCommand) {
 			CreateProcedureCommand cupc = (CreateProcedureCommand)currentCommand;
 			cupc.setVirtualGroup(container);
-
 			if (type == Command.TYPE_STORED_PROCEDURE) {
 				StoredProcedureInfo info = metadata.getStoredProcedureInfoForProcedure(container.getName());
 		        // Create temporary metadata that defines a group based on either the stored proc
@@ -281,15 +281,22 @@
 		        List<ElementSymbol> tempElements = new ArrayList<ElementSymbol>(info.getParameters().size());
 		        boolean[] updatable = new boolean[info.getParameters().size()];
 		        int i = 0;
+		        List<ElementSymbol> rsColumns = Collections.emptyList();
 		        for (SPParameter param : info.getParameters()) {
 		            if(param.getParameterType() != ParameterInfo.RESULT_SET) {
 		                ElementSymbol symbol = param.getParameterSymbol();
 		                tempElements.add(symbol);
 		                updatable[i++] = param.getParameterType() != ParameterInfo.IN;  
+		            } else {
+		            	rsColumns = param.getResultSetColumns();
 		            }
 		        }
-
 		        ProcedureContainerResolver.addScalarGroup(procName, childMetadata, externalGroups, tempElements, updatable);
+		        cupc.setResultSetColumns(rsColumns);
+		        //the relational planner will override this with the appropriate value
+		        cupc.setProjectedSymbols(rsColumns);
+			} else {
+    			cupc.setUpdateType(type);
 			}
 		}
 		

Modified: trunk/engine/src/main/java/org/teiid/query/resolver/QueryResolver.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/resolver/QueryResolver.java	2012-09-26 17:05:51 UTC (rev 4474)
+++ trunk/engine/src/main/java/org/teiid/query/resolver/QueryResolver.java	2012-09-26 23:15:59 UTC (rev 4475)
@@ -59,7 +59,6 @@
 import org.teiid.query.sql.lang.SubqueryContainer;
 import org.teiid.query.sql.lang.UnaryFromClause;
 import org.teiid.query.sql.navigator.DeepPostOrderNavigator;
-import org.teiid.query.sql.proc.CreateProcedureCommand;
 import org.teiid.query.sql.symbol.AliasSymbol;
 import org.teiid.query.sql.symbol.ElementSymbol;
 import org.teiid.query.sql.symbol.Expression;
@@ -103,14 +102,6 @@
     	if (command == null) {
     		return null;
     	}
-		if (command instanceof CreateProcedureCommand) {
-    		CreateProcedureCommand cupCommand = (CreateProcedureCommand)command;
-		    cupCommand.setUserCommand(proc);
-    		//if the subcommand is virtual stored procedure, it must have the same
-            //projected symbol as its parent.
-            cupCommand.setProjectedSymbols(proc.getProjectedSymbols());
-            cupCommand.setResultSetColumns(proc.getResultSetColumns());
-    	}
     	resolveCommand(command, proc.getGroup(), proc.getType(), metadata.getDesignTimeMetadata());
     	return command;
     }

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	2012-09-26 17:05:51 UTC (rev 4474)
+++ trunk/engine/src/main/java/org/teiid/query/resolver/command/UpdateProcedureResolver.java	2012-09-26 23:15:59 UTC (rev 4475)
@@ -22,7 +22,6 @@
 
 package org.teiid.query.resolver.command;
 
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.LinkedList;
@@ -67,11 +66,6 @@
  */
 public class UpdateProcedureResolver implements CommandResolver {
 	
-	public static class StatementNode {
-		CommandStatement cs;
-		List<StatementNode> children;
-	}
-	
 	public static final List<ElementSymbol> exceptionGroup;
 	static {
 		ElementSymbol es1 = new ElementSymbol("STATE"); //$NON-NLS-1$
@@ -95,7 +89,11 @@
     	
     	if (command instanceof TriggerAction) {
     		TriggerAction ta = (TriggerAction)command;
-            resolveBlock(new CreateProcedureCommand(), ta.getBlock(), ta.getExternalGroupContexts(), metadata, null);
+    		CreateProcedureCommand cmd = new CreateProcedureCommand(ta.getBlock());
+    		cmd.setVirtualGroup(ta.getView());
+    		//TODO: this is not generally correct - we should update the api to set the appropriate type
+    		cmd.setUpdateType(Command.TYPE_INSERT);
+            resolveBlock(cmd, ta.getBlock(), ta.getExternalGroupContexts(), metadata);
     		return;
     	}
 
@@ -112,41 +110,11 @@
         symbols.add(updateCount);
 
         ProcedureContainerResolver.addScalarGroup(ProcedureReservedWords.VARIABLES, metadata.getMetadataStore(), externalGroups, symbols);    
-        StatementNode sn = new StatementNode();
-        resolveBlock(procCommand, procCommand.getBlock(), externalGroups, metadata, sn);
-        
-        //validate the possible returned resultsets
-        if (procCommand.getResultSetColumns() == null || !procCommand.getResultSetColumns().isEmpty()) {
-            setReturnable(procCommand, sn);
-        }
+        resolveBlock(procCommand, procCommand.getBlock(), externalGroups, metadata);
     }
 
-	private void setReturnable(CreateProcedureCommand procCommand, StatementNode sn) {
-		if (sn.cs != null) {
-			sn.cs.setReturnable(true);
-			//this logic is for designer, which want's to populate a resultset from the proc text
-	        if (procCommand.getResultSetColumns() == null) {
-	        	List<? extends Expression> symbols = sn.cs.getCommand().getProjectedSymbols();
-		        if (sn.cs.getCommand() instanceof StoredProcedure) {
-		        	StoredProcedure sp = (StoredProcedure)sn.cs.getCommand();
-		        	if (sp.isCallableStatement()) {
-		        		symbols = sp.getResultSetColumns();
-		        	}
-		        }
-	        	procCommand.setResultSetColumns(symbols);
-	        	//TODO: what about out parameters
-	        	procCommand.setProjectedSymbols(symbols);
-	        }
-		}
-		if (sn.children != null) {
-			for (StatementNode child : sn.children) {
-				setReturnable(procCommand, child);
-			}
-		}
-	}
-
 	public void resolveBlock(CreateProcedureCommand command, Block block, GroupContext externalGroups, 
-                              TempMetadataAdapter metadata, org.teiid.query.resolver.command.UpdateProcedureResolver.StatementNode sn)
+                              TempMetadataAdapter metadata)
         throws QueryResolverException, QueryMetadataException, TeiidComponentException {
         LogManager.logTrace(org.teiid.logging.LogConstants.CTX_QUERY_RESOLVER, new Object[]{"Resolving block", block}); //$NON-NLS-1$
         
@@ -159,7 +127,7 @@
         GroupSymbol variables = ProcedureContainerResolver.addScalarGroup(ProcedureReservedWords.VARIABLES, store, externalGroups, new LinkedList<Expression>());
         
         for (Statement statement : block.getStatements()) {
-            resolveStatement(command, statement, externalGroups, variables, metadata, sn);
+            resolveStatement(command, statement, externalGroups, variables, metadata);
         }
         
         if (block.getExceptionGroup() != null) {
@@ -175,13 +143,13 @@
             if (block.getExceptionStatements() != null) {
             	ProcedureContainerResolver.addScalarGroup(block.getExceptionGroup(), store, externalGroups, exceptionGroup, false);
 	            for (Statement statement : block.getExceptionStatements()) {
-	                resolveStatement(command, statement, externalGroups, variables, metadata, sn);
+	                resolveStatement(command, statement, externalGroups, variables, metadata);
 	            }
             }
         }
     }
 
-	private void resolveStatement(CreateProcedureCommand command, Statement statement, GroupContext externalGroups, GroupSymbol variables, TempMetadataAdapter metadata, StatementNode sn)
+	private void resolveStatement(CreateProcedureCommand command, Statement statement, GroupContext externalGroups, GroupSymbol variables, TempMetadataAdapter metadata)
         throws QueryResolverException, QueryMetadataException, TeiidComponentException {
         LogManager.logTrace(org.teiid.logging.LogConstants.CTX_QUERY_RESOLVER, new Object[]{"Resolving statement", statement}); //$NON-NLS-1$
 
@@ -193,9 +161,9 @@
                 	resolveEmbeddedCommand(metadata, externalGroups, container.getCommand());
                 }
                 ResolverVisitor.resolveLanguageObject(ifCrit, null, externalGroups, metadata);
-            	resolveBlock(command, ifStmt.getIfBlock(), externalGroups, metadata, pushChild(sn));
+            	resolveBlock(command, ifStmt.getIfBlock(), externalGroups, metadata);
                 if(ifStmt.hasElseBlock()) {
-                    resolveBlock(command, ifStmt.getElseBlock(), externalGroups, metadata, pushChild(sn));
+                    resolveBlock(command, ifStmt.getElseBlock(), externalGroups, metadata);
                 }
                 break;
             case Statement.TYPE_COMMAND:
@@ -234,15 +202,19 @@
                     DynamicCommand dynCommand = (DynamicCommand)subCommand;
                     
                     if(dynCommand.getIntoGroup() == null
-                    		&& !dynCommand.isAsClauseSet() && !command.getProjectedSymbols().isEmpty()) {
-                        dynCommand.setAsColumns(command.getProjectedSymbols());
+                    		&& !dynCommand.isAsClauseSet()) {
+            		    if ((command.getResultSetColumns() != null && command.getResultSetColumns().isEmpty()) || !cmdStmt.isReturnable()) {
+            		    	//we're not interested in the resultset
+            		    	dynCommand.setAsColumns(Collections.EMPTY_LIST);
+            		    } else {
+            		    	//should match the procedure
+            		    	dynCommand.setAsColumns(command.getResultSetColumns());
+            		    }
                     }
                 }
-
-                //this could be the last select statement, set the projected symbol
-                //on the virtual procedure command
-                if (subCommand.returnsResultSet() && sn != null) {
-                	clearReturnableStatement(sn, cmdStmt);
+                
+                if (command.getResultSetColumns() == null && cmdStmt.isReturnable() && subCommand.returnsResultSet() && !subCommand.getResultSetColumns().isEmpty()) {
+                	command.setResultSetColumns(subCommand.getResultSetColumns());
                 }
 
                 break;
@@ -283,9 +255,6 @@
 	        		exprStmt.setExpression(ResolverUtil.convertExpression(exprStmt.getExpression(), varTypeName, metadata));     
 	        		if (statement.getType() == Statement.TYPE_ERROR) {
 	        			ResolverVisitor.checkException(exprStmt.getExpression());
-	        			if (!((RaiseStatement)statement).isWarning()) {
-	        				clearReturnableStatement(sn, null);
-	        			}
 	        		}
                 }
                 break;
@@ -296,7 +265,7 @@
                 	resolveEmbeddedCommand(metadata, externalGroups, container.getCommand());
                 }
                 ResolverVisitor.resolveLanguageObject(whileCrit, null, externalGroups, metadata);
-                resolveBlock(command, whileStmt.getBlock(), externalGroups, metadata, pushChild(sn));
+                resolveBlock(command, whileStmt.getBlock(), externalGroups, metadata);
                 break;
             case Statement.TYPE_LOOP:
                 LoopStatement loopStmt = (LoopStatement) statement;
@@ -314,24 +283,14 @@
                 
                 ProcedureContainerResolver.addScalarGroup(groupName, store, externalGroups, symbols, false);
                 
-                resolveBlock(command, loopStmt.getBlock(), externalGroups, metadata, pushChild(sn));
+                resolveBlock(command, loopStmt.getBlock(), externalGroups, metadata);
                 break;
             case Statement.TYPE_COMPOUND:
-            	resolveBlock(command, (Block)statement, externalGroups, metadata, sn);
+            	resolveBlock(command, (Block)statement, externalGroups, metadata);
             	break;
         }
     }
 
-	private void clearReturnableStatement(StatementNode sn,
-			CommandStatement cmdStmt) {
-		updateDynamicAs(sn);
-		
-		sn.cs = cmdStmt;
-		if (sn.children != null) {
-			sn.children.clear();
-		}
-	}
-
 	private void isValidGroup(TempMetadataAdapter metadata, String groupName)
 			throws QueryResolverException {
 		if (metadata.getMetadataStore().getTempGroupID(groupName) != null) {
@@ -344,32 +303,6 @@
 		}
 	}
 
-	private void updateDynamicAs(StatementNode sn) {
-		if (sn.cs != null && sn.cs.getCommand().getType() == Command.TYPE_DYNAMIC) {
-		    DynamicCommand dynamicCommand = (DynamicCommand)sn.cs.getCommand();
-		    if (!dynamicCommand.isAsClauseSet()) {
-		        dynamicCommand.setAsColumns(Collections.EMPTY_LIST);
-		    }
-		}
-		if (sn.children != null) {
-			for (StatementNode child : sn.children) {
-				updateDynamicAs(child);
-			}
-		}
-	}
-
-	private StatementNode pushChild(StatementNode sn) {
-		if (sn != null) {
-			if (sn.children == null) {
-				sn.children = new ArrayList<StatementNode>();
-			}
-			StatementNode child = new StatementNode();
-			sn.children.add(child);
-			sn = child;
-		}
-		return sn;
-	}
-
 	private boolean isAssignable(TempMetadataAdapter metadata, SPParameter param)
 			throws TeiidComponentException, QueryMetadataException {
 		if (!(param.getExpression() instanceof ElementSymbol)) {

Modified: trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java	2012-09-26 17:05:51 UTC (rev 4474)
+++ trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java	2012-09-26 23:15:59 UTC (rev 4475)
@@ -232,15 +232,13 @@
         return command;
 	}
     
-	private Command rewriteUpdateProcedure(CreateProcedureCommand command)
-								 throws TeiidComponentException, TeiidProcessingException{
+	private Command rewriteUpdateProcedure(CreateProcedureCommand command) throws TeiidComponentException {
 		Block block = rewriteBlock(command.getBlock());
         command.setBlock(block);
         return command;
 	}
 
-	private Block rewriteBlock(Block block)
-								 throws TeiidComponentException, TeiidProcessingException{
+	private Block rewriteBlock(Block block) throws TeiidComponentException {
 		List<Statement> statements = block.getStatements();
         List<Statement> newStmts = rewriteStatements(statements);
         block.setStatements(newStmts);
@@ -250,15 +248,23 @@
         return block;
 	 }
 
-	private List<Statement> rewriteStatements(List<Statement> statements)
-			throws TeiidComponentException, TeiidProcessingException {
+	private List<Statement> rewriteStatements(List<Statement> statements) throws TeiidComponentException {
 		Iterator<Statement> stmtIter = statements.iterator();
 
 		List<Statement> newStmts = new ArrayList<Statement>(statements.size());
 		// plan each statement in the block
         while(stmtIter.hasNext()) {
 			Statement stmnt = stmtIter.next();
-			rewriteStatement(stmnt, newStmts);
+			try {
+				rewriteStatement(stmnt, newStmts);
+			} catch (TeiidProcessingException e) {
+				/*
+				 * defer the processing of the exception until runtime as there may be an exception handler
+				 */
+				RaiseStatement raise = new RaiseStatement(new Constant(e));
+				newStmts.add(raise);
+				break;
+			}
         }
 		return newStmts;
 	}
@@ -343,9 +349,7 @@
                 crit = rewriteCriteria(crit);
                 
                 whileStatement.setCondition(crit);
-                if(crit.equals(TRUE_CRITERIA)) {
-                     throw new QueryValidatorException(QueryPlugin.Event.TEIID30367, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30367));
-                } else if(crit.equals(FALSE_CRITERIA) || crit.equals(UNKNOWN_CRITERIA)) {
+                if(crit.equals(FALSE_CRITERIA) || crit.equals(UNKNOWN_CRITERIA)) {
                     return;
                 } 
                 whileStatement.setBlock(rewriteBlock(whileStatement.getBlock()));
@@ -354,6 +358,9 @@
                     return;
                 }
                 break;
+            case Statement.TYPE_COMPOUND:
+            	statement = rewriteBlock((Block) statement);
+            	break;
 		}
 		newStmts.add(statement);
 	}

Modified: trunk/engine/src/main/java/org/teiid/query/sql/lang/BatchedUpdateCommand.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/lang/BatchedUpdateCommand.java	2012-09-26 17:05:51 UTC (rev 4474)
+++ trunk/engine/src/main/java/org/teiid/query/sql/lang/BatchedUpdateCommand.java	2012-09-26 23:15:59 UTC (rev 4475)
@@ -102,30 +102,15 @@
     public String toString() {
         StringBuffer val = new StringBuffer("BatchedUpdate{"); //$NON-NLS-1$
         if (commands != null && commands.size() > 0) {
-            val.append(getCommandToken(commands.get(0)));
+            val.append(getCommandToken(commands.get(0).getType()));
             for (int i = 1; i < commands.size(); i++) {
-                val.append(',').append(getCommandToken(commands.get(i)));
+                val.append(',').append(getCommandToken(commands.get(i).getType()));
             }
         }
         val.append('}');
         return val.toString();
     }
     
-    private char getCommandToken(Command command) {
-        int commandType = command.getType();
-        if (commandType == Command.TYPE_INSERT) {
-            return 'I';
-        } else if (commandType == Command.TYPE_UPDATE) {
-            return 'U';
-        } else if (commandType == Command.TYPE_DELETE) {
-            return 'D';
-        } else if (commandType == Command.TYPE_QUERY) {
-            // SELECT INTO command
-            return 'S';
-        }
-        return '?';
-    }
-
 	public void setVariableContexts(List<VariableContext> variableContexts) {
 		this.variableContexts = variableContexts;
 	}

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	2012-09-26 17:05:51 UTC (rev 4474)
+++ trunk/engine/src/main/java/org/teiid/query/sql/lang/Command.java	2012-09-26 23:15:59 UTC (rev 4475)
@@ -75,11 +75,6 @@
 	public static final int TYPE_DELETE = 4;
 
 	/**
-	 * Represents any SQL statement, wrapped as a string
-	 */
-	public static final int TYPE_SQL = 5;
-
-	/**
 	 * Represents a stored procedure command
 	 */
     public static final int TYPE_STORED_PROCEDURE = 6;
@@ -349,4 +344,46 @@
     public boolean returnsResultSet() {
         return false;
     }
+    
+    /**
+     * @return null if unknown, empty if results are not returned, or the resultset columns
+     */
+	public List<? extends Expression> getResultSetColumns() {
+		if (returnsResultSet()) {
+			return getProjectedSymbols();
+		}
+		return Collections.emptyList();
+	}
+	
+	//TODO: replace with enum
+	public static String getCommandToken(int commandType) {
+		switch (commandType) {
+		case Command.TYPE_INSERT:
+			return "I"; //$NON-NLS-1$
+		case Command.TYPE_UPDATE:
+			return "U"; //$NON-NLS-1$
+		case Command.TYPE_DELETE:
+			return "D"; //$NON-NLS-1$
+		case Command.TYPE_DROP:
+			return "DT"; //$NON-NLS-1$
+		case Command.TYPE_ALTER_PROC:
+			return "AP"; //$NON-NLS-1$
+		case Command.TYPE_ALTER_TRIGGER:
+			return "AT"; //$NON-NLS-1$
+		case Command.TYPE_ALTER_VIEW:
+			return "AV"; //$NON-NLS-1$
+		case Command.TYPE_CREATE:
+			return "CT"; //$NON-NLS-1$
+		case Command.TYPE_DYNAMIC:
+			return "Dy"; //$NON-NLS-1$
+		case Command.TYPE_QUERY:
+			return "S"; //$NON-NLS-1$
+		case Command.TYPE_STORED_PROCEDURE:
+			return "Sp"; //$NON-NLS-1$
+		case Command.TYPE_UPDATE_PROCEDURE:
+			return "Up"; //$NON-NLS-1$
+		}
+        return "?"; //$NON-NLS-1$
+    }
+
 }

Modified: trunk/engine/src/main/java/org/teiid/query/sql/lang/DynamicCommand.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/lang/DynamicCommand.java	2012-09-26 17:05:51 UTC (rev 4474)
+++ trunk/engine/src/main/java/org/teiid/query/sql/lang/DynamicCommand.java	2012-09-26 23:15:59 UTC (rev 4475)
@@ -260,5 +260,14 @@
     public boolean returnsResultSet() {
     	return intoGroup == null;
     }
+    
+    @SuppressWarnings("unchecked")
+	@Override
+    public List<? extends Expression> getResultSetColumns() {
+    	if (returnsResultSet()) {
+    		return asColumns;
+    	}
+    	return Collections.emptyList();
+    }
 
 }

Modified: trunk/engine/src/main/java/org/teiid/query/sql/lang/ProcedureContainer.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/lang/ProcedureContainer.java	2012-09-26 17:05:51 UTC (rev 4474)
+++ trunk/engine/src/main/java/org/teiid/query/sql/lang/ProcedureContainer.java	2012-09-26 23:15:59 UTC (rev 4475)
@@ -22,8 +22,6 @@
 
 package org.teiid.query.sql.lang;
 
-import java.util.List;
-
 import org.teiid.query.validator.UpdateValidator.UpdateInfo;
 
 
@@ -66,9 +64,5 @@
     public void setUpdateInfo(UpdateInfo updateInfo) {
 		this.updateInfo = updateInfo;
 	}
-
-	public List getResultSetColumns() {
-		return getProjectedSymbols();
-	}
     
 }

Modified: trunk/engine/src/main/java/org/teiid/query/sql/proc/CommandStatement.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/proc/CommandStatement.java	2012-09-26 17:05:51 UTC (rev 4474)
+++ trunk/engine/src/main/java/org/teiid/query/sql/proc/CommandStatement.java	2012-09-26 23:15:59 UTC (rev 4475)
@@ -37,7 +37,7 @@
 
 	// the command this statement represents
 	Command command;
-	private boolean returnable;
+	private boolean returnable = true;
 
 	/**
 	 * Constructor for CommandStatement.

Modified: trunk/engine/src/main/java/org/teiid/query/sql/proc/CreateProcedureCommand.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/proc/CreateProcedureCommand.java	2012-09-26 17:05:51 UTC (rev 4474)
+++ trunk/engine/src/main/java/org/teiid/query/sql/proc/CreateProcedureCommand.java	2012-09-26 23:15:59 UTC (rev 4475)
@@ -46,15 +46,12 @@
 	// top level block for the procedure
 	private Block block;
 	
-	// the command the user submitted against the virtual group being updated
-	private Command userCommand;
-	
     private List projectedSymbols;
-    private List resultSetColumns;
+    private List<? extends Expression> resultSetColumns;
     
     private GroupSymbol virtualGroup;
 
-	private String updateType;
+	private int updateType = Command.TYPE_UNKNOWN;
 
 	/**
 	 * Constructor for CreateUpdateProcedureCommand.
@@ -96,22 +93,6 @@
 		this.block = block;
 	}
 
-	/**
-	 * Set the user's command to which this obj which is the subcommand
-	 * @param command The user's command
-	 */
-	public void setUserCommand(Command command) {
-		this.userCommand = command;
-	}
-
-	/**
-	 * Get the user's command to which this obj which is the subcommand
-	 * @return The user's command
-	 */	
-	public Command getUserCommand() {
-		return this.userCommand;	
-	}	
-
     // =========================================================================
     //                  P R O C E S S I N G     M E T H O D S
     // =========================================================================
@@ -207,11 +188,11 @@
         return Collections.EMPTY_LIST;
 	}  
 	
-	public List getResultSetColumns() {
+	public List<? extends Expression> getResultSetColumns() {
 		return resultSetColumns;
 	}
 	
-	public void setResultSetColumns(List resultSetColumns) {
+	public void setResultSetColumns(List<? extends Expression> resultSetColumns) {
 		this.resultSetColumns = resultSetColumns;
 	}
 	
@@ -237,11 +218,12 @@
         this.virtualGroup = virtualGroup;
     }
 
-	public void setUpdateType(String updateType) {
-		this.updateType = updateType;
+	public void setUpdateType(int type) {
+		this.resultSetColumns = Collections.emptyList();
+		this.updateType = type;
 	}
 	
-	public String getUpdateType() {
+	public int getUpdateType() {
 		return updateType;
 	}
 

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	2012-09-26 17:05:51 UTC (rev 4474)
+++ trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java	2012-09-26 23:15:59 UTC (rev 4475)
@@ -47,7 +47,6 @@
 import org.teiid.query.sql.lang.TextTable.TextColumn;
 import org.teiid.query.sql.lang.XMLTable.XMLColumn;
 import org.teiid.query.sql.proc.*;
-import org.teiid.query.sql.proc.BranchingStatement.BranchingMode;
 import org.teiid.query.sql.proc.Statement.Labeled;
 import org.teiid.query.sql.symbol.*;
 import org.teiid.query.sql.symbol.AggregateSymbol.Type;
@@ -1418,6 +1417,12 @@
 
     public void visit( CommandStatement obj ) {
         visitNode(obj.getCommand());
+        if (!obj.isReturnable()) {
+        	append(SPACE);
+        	append(WITHOUT);
+        	append(SPACE);
+        	append(RETURN);
+        }
         append(";"); //$NON-NLS-1$
     }
 

Modified: trunk/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java	2012-09-26 17:05:51 UTC (rev 4474)
+++ trunk/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java	2012-09-26 23:15:59 UTC (rev 4475)
@@ -408,11 +408,14 @@
 
     public void visit(CreateProcedureCommand obj) {
         //check that the procedure does not contain references to itself
-    	if (obj.getUpdateType() == null) {
+    	if (obj.getUpdateType() == Command.TYPE_UNKNOWN) {
 	        if (GroupCollectorVisitor.getGroups(obj,true).contains(obj.getVirtualGroup())) {
 	        	handleValidationError(QueryPlugin.Util.getString("ValidationVisitor.Procedure_has_group_self_reference"),obj); //$NON-NLS-1$
 	        }
-	        this.createProc = obj;
+	        if (obj.getResultSetColumns() != null) {
+	        	//some unit tests bypass setting the columns
+		        this.createProc = obj;
+	        }
     	}
     }
 
@@ -1471,20 +1474,20 @@
     
     @Override
     public void visit(CommandStatement obj) {
-    	if (obj.isReturnable() && this.createProc != null) {
-    		List<? extends Expression> symbols = obj.getCommand().getProjectedSymbols();
-	        if (obj.getCommand() instanceof StoredProcedure) {
-	        	StoredProcedure sp = (StoredProcedure)obj.getCommand();
-	        	if (sp.isCallableStatement()) {
-	        		symbols = sp.getResultSetColumns();
-	        	}
-	        }
-    		try {
-				QueryResolver.validateProjectedSymbols(createProc.getVirtualGroup(), createProc.getResultSetColumns(), symbols);
-			} catch (QueryValidatorException e) {
-				handleValidationError(QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31121, createProc.getVirtualGroup(), obj, e.getMessage()), obj);
-			}
+    	if (this.createProc == null || this.createProc.getResultSetColumns().isEmpty() || !obj.isReturnable() || !obj.getCommand().returnsResultSet()) {
+    		return;
     	}
+		List<? extends Expression> symbols = obj.getCommand().getResultSetColumns();
+		if (symbols == null && obj.getCommand() instanceof DynamicCommand) {
+			DynamicCommand cmd = (DynamicCommand)obj.getCommand();
+			cmd.setAsColumns(this.createProc.getResultSetColumns());
+			return;
+		}
+		try {
+			QueryResolver.validateProjectedSymbols(createProc.getVirtualGroup(), createProc.getResultSetColumns(), symbols);
+		} catch (QueryValidatorException e) {
+			handleValidationError(QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31121, createProc.getVirtualGroup(), obj, e.getMessage()), obj);
+		}
     }
     
     @Override

Modified: trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj
===================================================================
--- trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj	2012-09-26 17:05:51 UTC (rev 4474)
+++ trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj	2012-09-26 23:15:59 UTC (rev 4475)
@@ -906,7 +906,7 @@
 /*
 name=raise statement
 description=Raises an error or warning with the given message.
-example={code:sql}RAISE SQLEXCEPTION '00A' 'something went wrong'{code}
+example={code:sql}RAISE SQLEXCEPTION 'something went wrong'{code}
 */
 RaiseStatement raiseStatement(ParseInfo info) :
 {
@@ -1187,7 +1187,7 @@
     {
         variableID = new ElementSymbol(var);
     }
-    [[<COLON>]<EQ>
+    [<EQ>
      value = assignStatementOperand(info)
     ]
     
@@ -1205,28 +1205,31 @@
 /*
 name=assignment statement
 description=Assigns a variable a value in a procedure.
-example={code:sql}x := 'b'{code}
+example={code:sql}x = 'b'{code}
 */
 Statement assignStatement(ParseInfo info) :
 {
     LanguageObject value = null;
     String var = null;
     ElementSymbol elementID = null;
+    boolean returnable=true;
 }
 {
     var = id()
     {
         elementID = new ElementSymbol(var);              
     } 
-    [<COLON>]<EQ>
+    <EQ>
     (value = assignStatementOperand(info) |
-     value = storedProcedure(info, 2) {
+     (value = storedProcedure(info, 2) [(<WITH>|<WITHOUT> {returnable = false;}) <RETURN>]) {
 		StoredProcedure storedProcedure = (StoredProcedure)value;
 	    SPParameter parameter = new SPParameter(1, SPParameter.RETURN_VALUE, "return"); //$NON-NLS-1$
 	    parameter.setExpression(elementID);
 		storedProcedure.setParameter(parameter);  
-		storedProcedure.setCalledWithReturn(true);            
-		return new CommandStatement(storedProcedure);      	    
+		storedProcedure.setCalledWithReturn(true);
+		CommandStatement cs = new CommandStatement(storedProcedure);
+		cs.setReturnable(returnable);
+		return cs;      	    
      }
     )
         
@@ -1265,7 +1268,7 @@
 
 /*
 name=data statement
-description=A procedure statement that executes a SQL statement.  An update statement can have its update count accessed via the ROWS_UPDATED variable. 
+description=A procedure statement that executes a SQL statement.  An update statement can have its update count accessed via the ROWCOUNT variable. 
 */
 CommandStatement sqlStatement(ParseInfo info) :
 {
@@ -1273,14 +1276,17 @@
     String var = null;
     ElementSymbol elementID = null;
     StoredProcedure storedProcedure = null;
+    boolean returnable = true;
 }
 {
     (LOOKAHEAD(2) cmd = userCommand(info) |
      cmd = dynamicCommand(info)
-    )
+    ) [(<WITH>|<WITHOUT> {returnable = false;}) <RETURN>]
   
     {
-    	return new CommandStatement(cmd);
+    	CommandStatement cs = new CommandStatement(cmd);
+    	cs.setReturnable(returnable);
+    	return cs;
     }   
 }
  

Modified: trunk/engine/src/main/resources/org/teiid/query/i18n.properties
===================================================================
--- trunk/engine/src/main/resources/org/teiid/query/i18n.properties	2012-09-26 17:05:51 UTC (rev 4474)
+++ trunk/engine/src/main/resources/org/teiid/query/i18n.properties	2012-09-26 23:15:59 UTC (rev 4475)
@@ -752,8 +752,6 @@
 XMLQuery.resolvingError=Failed to resolve the query ''{0}''
 TEIID30085=Invalid order by at {0}
 
-TEIID30367=Infinite loop detected, procedure will not be executed.
-
 TEIID30244=The batch contained an unrecognized command: {0}
 TEIID30272=Error getting modelID
 TEIID30213=Cannot find namespace URI for namespace {0} of element {1}
@@ -1032,7 +1030,8 @@
 TEIID31115=Function based index {1} expression {0} is not deterministic.
 TEIID31116=Function based index {1} expression {0} could not be resolved: {2}
 TEIID31120=An exception may only be chained to another exception. {0} is not valid.
-TEIID31121=The expected result set of the procedure {0} does not match the result set from returnable statement {1} - {2}
+TEIID31121=The expected result set of the procedure {0} does not match the result set from returnable statement {1} use WITHOUT RETURN to indicate the statement should not be returned - {2}
+TEIID31122=Null exception reference.
 
 SQLParser.proc_type_conflict=Result type {1} conflicts with return type {2} for procedure {0}
 SQLParser.param_out=Procedure {0} RESULT param {1} must be of type OUT.

Modified: trunk/engine/src/test/java/org/teiid/query/processor/TestTriggerActions.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/TestTriggerActions.java	2012-09-26 17:05:51 UTC (rev 4474)
+++ trunk/engine/src/test/java/org/teiid/query/processor/TestTriggerActions.java	2012-09-26 23:15:59 UTC (rev 4475)
@@ -122,7 +122,7 @@
 	    	helpProcess(plan, context, dm, null);
 	    	fail();
         } catch (QueryProcessingException e) {
-        	assertEquals("TEIID30168 Couldn't execute the dynamic SQL command \"EXECUTE IMMEDIATE 'delete from gx where gx.x = new.x'\" with the SQL statement \"'delete from gx where gx.x = new.x'\" due to: TEIID30347 There is a recursive invocation of group 'Insert gx'. Please correct the SQL.", e.getMessage());
+        	assertEquals("TEIID30168 Couldn't execute the dynamic SQL command \"EXECUTE IMMEDIATE 'delete from gx where gx.x = new.x'\" with the SQL statement \"'delete from gx where gx.x = new.x'\" due to: TEIID30347 There is a recursive invocation of group 'I gx'. Please correct the SQL.", e.getMessage());
         }
 	}
 	

Modified: trunk/engine/src/test/java/org/teiid/query/processor/proc/TestProcErrors.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/proc/TestProcErrors.java	2012-09-26 17:05:51 UTC (rev 4474)
+++ trunk/engine/src/test/java/org/teiid/query/processor/proc/TestProcErrors.java	2012-09-26 23:15:59 UTC (rev 4475)
@@ -74,7 +74,20 @@
         	assertEquals("abc", tse.getSQLState());
         	assertEquals(1, tse.getErrorCode());
         }
+    }
+    
+    @Test public void testExceptionGroup() throws Exception {
+    	String ddl = 
+    			"create virtual procedure vproc () returns string as begin select 1/0; exception e \"return\" = e.state || ' ' || e.errorcode || ' ' || e.teiidcode || ' ' || cast(e.exception as string) || ' ' || cast(e.chain as string); end;";
+    	TransformationMetadata tm = TestProcedureResolving.createMetadata(ddl);    	
+
+    	String sql = "call vproc()"; //$NON-NLS-1$
+
+        ProcessorPlan plan = getProcedurePlan(sql, tm);
+
+        HardcodedDataManager dataManager = new HardcodedDataManager(tm);
         
+    	helpTestProcess(plan, new List[] {Arrays.asList("50000 30328 TEIID30328 org.teiid.jdbc.TeiidSQLException: TEIID30328 Unable to evaluate (1 / 0): TEIID30384 Error while evaluating function / org.teiid.api.exception.query.ExpressionEvaluationException: TEIID30328 Unable to evaluate (1 / 0): TEIID30384 Error while evaluating function /")}, dataManager, tm);
     }
     
     @Test public void testExceptionHandling() throws Exception {
@@ -99,5 +112,39 @@
     	assertEquals("caught", tse.getMessage());
     	assertEquals("hello world", tse.getCause().getMessage());
     }
+    
+    /**
+     * ensures that a processing error is trappable 
+     */
+    @Test public void testExceptionHandlingWithResultSet() throws Exception {
+    	String ddl = 
+    			"create virtual procedure proc2 (x integer) as begin atomic select 1; begin select 1/x; end exception e end;";
+    	TransformationMetadata tm = TestProcedureResolving.createMetadata(ddl);    	
+
+    	String sql = "call proc2(0)"; //$NON-NLS-1$
+
+        ProcessorPlan plan = getProcedurePlan(sql, tm);
+
+        HardcodedDataManager dataManager = new HardcodedDataManager(tm);
+        
+    	helpTestProcess(plan, new List[] {Arrays.asList(1)}, dataManager, tm);
+    }
+    
+    /**
+     * ensures that the whole result is formed so that the error does not escape the handler
+     */
+    @Test public void testExceptionHandlingWithResultSet1() throws Exception {
+    	String ddl = 
+    			"create virtual procedure proc2 (x integer) as begin create local temporary table t (i integer); insert into t (i) values (1); declare integer y = 0; while (y < 16) begin insert into t (i) select 1 from t; y = y+1; end insert into t (i) values (0); select cast(1/i as string) from t; exception e end;";
+    	TransformationMetadata tm = TestProcedureResolving.createMetadata(ddl);    	
+
+    	String sql = "call proc2(0)"; //$NON-NLS-1$
+
+        ProcessorPlan plan = getProcedurePlan(sql, tm);
+
+        HardcodedDataManager dataManager = new HardcodedDataManager(tm);
+        
+    	helpTestProcess(plan, new List[0], dataManager, tm);
+    }
 	
 }

Modified: trunk/engine/src/test/java/org/teiid/query/processor/proc/TestProcedureProcessor.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/proc/TestProcedureProcessor.java	2012-09-26 17:05:51 UTC (rev 4474)
+++ trunk/engine/src/test/java/org/teiid/query/processor/proc/TestProcedureProcessor.java	2012-09-26 23:15:59 UTC (rev 4475)
@@ -930,7 +930,6 @@
         	helpTestProcess(plan, null, dataMgr, metadata);
         	fail("exception expected");
         } catch (QueryProcessingException e) {
-        	assertTrue(e.getCause() instanceof QueryValidatorException);
         }
     }
 
@@ -2056,7 +2055,7 @@
     }
     
     @Test public void testNestedBlock() throws Exception {
-    	String ddl = "create virtual procedure proc (z STRING) returns table (x string, y string) as begin declare string x = z; select x; begin select x, x; end end;";
+    	String ddl = "create virtual procedure proc (z STRING) returns table (x string, y string) as begin declare string x = z; select x without return; begin select x, x; end end;";
     	TransformationMetadata tm = TestProcedureResolving.createMetadata(ddl);    	
         String sql = "call proc('a')"; //$NON-NLS-1$
 

Modified: trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java	2012-09-26 17:05:51 UTC (rev 4474)
+++ trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java	2012-09-26 23:15:59 UTC (rev 4475)
@@ -38,7 +38,6 @@
 import org.junit.Ignore;
 import org.junit.Test;
 import org.teiid.api.exception.query.QueryMetadataException;
-import org.teiid.api.exception.query.QueryValidatorException;
 import org.teiid.client.metadata.ParameterInfo;
 import org.teiid.common.buffer.BufferManagerFactory;
 import org.teiid.core.TeiidComponentException;
@@ -1107,26 +1106,6 @@
         helpTestRewriteCriteria("(pm1.g1.e1 = 1 and pm1.g1.e2 = 2) and (pm1.g1.e3 = 1 and pm1.g1.e4 = 2.0e0)", "(pm1.g1.e1 = '1') AND (pm1.g1.e2 = 2) AND (pm1.g1.e3 = TRUE) AND (pm1.g1.e4 = 2.0e0)"); //$NON-NLS-1$ //$NON-NLS-2$
     }
     
-    @Test public void testRewriteWhile() throws Exception {
-        
-        String procedure = "FOR EACH ROW\n"; //$NON-NLS-1$
-        procedure = procedure + "BEGIN\n";       //$NON-NLS-1$
-        procedure = procedure + "while (1 = 1)\n"; //$NON-NLS-1$
-        procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
-        procedure = procedure + "Select vm1.g1.e1 from vm1.g1;\n"; //$NON-NLS-1$
-        procedure = procedure + "END\n"; //$NON-NLS-1$
-        procedure = procedure + "END\n"; //$NON-NLS-1$
-        
-        String userQuery = "Insert into vm1.g1 (e1, e2) values ('String', 1)"; //$NON-NLS-1$
-
-        try {       
-            getRewritenProcedure(procedure, userQuery, Table.TriggerEvent.INSERT);
-            fail("exception expected"); //$NON-NLS-1$
-        } catch (QueryValidatorException e) {
-            assertEquals("TEIID30367 Infinite loop detected, procedure will not be executed.", e.getMessage()); //$NON-NLS-1$
-        }
-    }
-    
     @Test public void testRewriteWhile1() throws Exception {
         
         String procedure = "FOR EACH ROW\n"; //$NON-NLS-1$
@@ -1196,6 +1175,17 @@
         String expected = "CREATE VIRTUAL PROCEDURE\nBEGIN\nBEGIN ATOMIC\nSELECT e1 FROM pm1.g1;\nEND\nEND"; //$NON-NLS-1$
         
         helpTestRewriteCommand(procedure1, expected);
+    }
+    
+    @Test public void testExceptionHandling() {
+        String procedure1 = "CREATE virtual PROCEDURE begin "; //$NON-NLS-1$
+        procedure1 += "select 1/0;\n"; //$NON-NLS-1$
+        procedure1 += "exception e\n"; //$NON-NLS-1$
+        procedure1 += "end\n"; //$NON-NLS-1$
+        
+        String expected = "CREATE VIRTUAL PROCEDURE\nBEGIN\nRAISE 'org.teiid.api.exception.query.ExpressionEvaluationException: TEIID30328 Unable to evaluate (1 / 0): TEIID30384 Error while evaluating function /';\nEXCEPTION e\nEND"; //$NON-NLS-1$
+        
+        helpTestRewriteCommand(procedure1, expected);
     }
     
     @Test public void testRewriteDeclare() {

Modified: trunk/engine/src/test/java/org/teiid/query/sql/visitor/TestSQLStringVisitor.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/sql/visitor/TestSQLStringVisitor.java	2012-09-26 17:05:51 UTC (rev 4474)
+++ trunk/engine/src/test/java/org/teiid/query/sql/visitor/TestSQLStringVisitor.java	2012-09-26 23:15:59 UTC (rev 4475)
@@ -1381,6 +1381,20 @@
 		helpTest(cmdStmt, "SELECT x FROM g;"); //$NON-NLS-1$
     }
     
+    @Test public void testCommandStatement1a() {
+        Query q1 = new Query();
+        Select select = new Select();
+        select.addSymbol(new ElementSymbol("x"));        //$NON-NLS-1$
+        q1.setSelect(select);        
+        From from = new From();
+        from.addGroup(new GroupSymbol("g")); //$NON-NLS-1$
+        q1.setFrom(from);
+            	
+    	CommandStatement cmdStmt =	new CommandStatement(q1);
+    	cmdStmt.setReturnable(false);
+		helpTest(cmdStmt, "SELECT x FROM g WITHOUT RETURN;"); //$NON-NLS-1$
+    }
+    
     @Test public void testCommandStatement2() {
         Delete d1 = new Delete();
         d1.setGroup(new GroupSymbol("g")); //$NON-NLS-1$

Modified: trunk/engine/src/test/java/org/teiid/query/unittest/RealMetadataFactory.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/unittest/RealMetadataFactory.java	2012-09-26 17:05:51 UTC (rev 4474)
+++ trunk/engine/src/test/java/org/teiid/query/unittest/RealMetadataFactory.java	2012-09-26 23:15:59 UTC (rev 4475)
@@ -301,7 +301,7 @@
         
         ColumnSet<Procedure> vsprs7 = createResultSet("TEIIDSP7.vsprs1", new String[] { "StringKey" }, new String[] { DataTypeManager.DefaultDataTypes.STRING }); //$NON-NLS-1$ //$NON-NLS-2$
         ProcedureParameter vsp7p1 = createParameter("p1", ParameterInfo.IN, DataTypeManager.DefaultDataTypes.INTEGER); //$NON-NLS-1$
-        QueryNode vspqn7 = new QueryNode("CREATE VIRTUAL PROCEDURE BEGIN declare integer x; x = exec spTest9(p1); declare integer y; exec spTest11(inkey=>x, outkey=>y); select convert(x, string) || y; END"); //$NON-NLS-1$ //$NON-NLS-2$
+        QueryNode vspqn7 = new QueryNode("CREATE VIRTUAL PROCEDURE BEGIN declare integer x; x = exec spTest9(p1); declare integer y; exec spTest11(inkey=>x, outkey=>y) without return; select convert(x, string) || y; END"); //$NON-NLS-1$ //$NON-NLS-2$
         Procedure vsp7 = createVirtualProcedure("TEIIDSP7", mmspTest1, Arrays.asList(vsp7p1), vspqn7); //$NON-NLS-1$
         vsp7.setResultSet(vsprs7);
         

Modified: trunk/engine/src/test/java/org/teiid/query/validator/TestAlterValidation.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/validator/TestAlterValidation.java	2012-09-26 17:05:51 UTC (rev 4474)
+++ trunk/engine/src/test/java/org/teiid/query/validator/TestAlterValidation.java	2012-09-26 23:15:59 UTC (rev 4475)
@@ -46,7 +46,7 @@
 	
 	@Test public void testValidateAlterProcedure() {
 		TestValidator.helpValidate("alter procedure spTest8a as begin select 1; end", new String[] {"spTest8a"}, RealMetadataFactory.exampleBQTCached());
-		TestValidator.helpValidate("alter procedure MMSP1 as begin select 1; end", new String[] {"BEGIN\nSELECT 1;\nEND"}, RealMetadataFactory.exampleBQTCached());
+		TestValidator.helpValidate("alter procedure MMSP1 as begin select 1; end", new String[] {"SELECT 1;"}, RealMetadataFactory.exampleBQTCached());
 	}
 	
 }

Modified: trunk/engine/src/test/java/org/teiid/query/validator/TestValidator.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/validator/TestValidator.java	2012-09-26 17:05:51 UTC (rev 4474)
+++ trunk/engine/src/test/java/org/teiid/query/validator/TestValidator.java	2012-09-26 23:15:59 UTC (rev 4475)
@@ -1469,7 +1469,7 @@
                                 .append("BEGIN\n") //$NON-NLS-1$
                                 .append("CREATE LOCAL TEMPORARY TABLE x (column1 string);") //$NON-NLS-1$
                                 .append("execute string 'SELECT e1 FROM pm1.g2' as e1 string INTO x;\n") //$NON-NLS-1$
-                                .append("select column1 from x;\n") //$NON-NLS-1$
+                                .append("select cast(column1 as integer) from x;\n") //$NON-NLS-1$
                                 .append("END\n"); //$NON-NLS-1$
         
         QueryMetadataInterface metadata = RealMetadataFactory.example1Cached();

Modified: trunk/runtime/src/main/java/org/teiid/runtime/EmbeddedServer.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/runtime/EmbeddedServer.java	2012-09-26 17:05:51 UTC (rev 4474)
+++ trunk/runtime/src/main/java/org/teiid/runtime/EmbeddedServer.java	2012-09-26 23:15:59 UTC (rev 4475)
@@ -265,6 +265,8 @@
 	protected boolean detectTransactions = true;
 	private Boolean running;
 	private EmbeddedConfiguration config;
+	private SessionAwareCache<CachedResults> rs;
+	private SessionAwareCache<PreparedPlan> ppc;
 	
 	public EmbeddedServer() {
 
@@ -321,8 +323,8 @@
 
 		startVDBRepository();
 
-		SessionAwareCache<CachedResults> rs = new SessionAwareCache<CachedResults>("resultset", config.getCacheFactory(), SessionAwareCache.Type.RESULTSET, config.getMaxResultSetCacheStaleness()); //$NON-NLS-1$
-		SessionAwareCache<PreparedPlan> ppc = new SessionAwareCache<PreparedPlan>("preparedplan", config.getCacheFactory(), SessionAwareCache.Type.PREPAREDPLAN, 0); //$NON-NLS-1$
+		rs = new SessionAwareCache<CachedResults>("resultset", config.getCacheFactory(), SessionAwareCache.Type.RESULTSET, config.getMaxResultSetCacheStaleness()); //$NON-NLS-1$
+		ppc = new SessionAwareCache<PreparedPlan>("preparedplan", config.getCacheFactory(), SessionAwareCache.Type.PREPAREDPLAN, 0); //$NON-NLS-1$
 		rs.setTupleBufferCache(bs.getTupleBufferCache());
 		this.dqp.setResultsetCache(rs);
 
@@ -378,6 +380,8 @@
 				if (replicator != null) {
 					replicator.stop(vdb.getVDB().getAttachment(GlobalTableStore.class));
 				}
+				rs.clearForVDB(name, 1);
+				ppc.clearForVDB(name, 1);
 			}
 
 			@Override
@@ -500,6 +504,7 @@
 	}
 	
 	public void undeployVDB(String vdbName) {
+		checkStarted();
 		this.repo.removeVDB(vdbName, 1);
 	}
 

Modified: trunk/runtime/src/test/java/org/teiid/runtime/TestEmbeddedServer.java
===================================================================
--- trunk/runtime/src/test/java/org/teiid/runtime/TestEmbeddedServer.java	2012-09-26 17:05:51 UTC (rev 4474)
+++ trunk/runtime/src/test/java/org/teiid/runtime/TestEmbeddedServer.java	2012-09-26 23:15:59 UTC (rev 4475)
@@ -332,7 +332,8 @@
 		mmd1.setSchemaSourceType("ddl");
 		mmd1.setSchemaText("create view v as select 1; " +
 				"create virtual procedure proc () options (updatecount 2) as begin select * from v; end; " +
-				"create virtual procedure proc1 () as begin atomic select * from v; end; ");
+				"create virtual procedure proc1 () as begin atomic select * from v; end; " +
+				"create virtual procedure proc2 (x integer) as begin atomic select 1; begin select 1/x; end exception e end;");
 
 		es.deployVDB("test", mmd1);
 		
@@ -365,6 +366,14 @@
 		s.execute("set noexec on");
 		s.execute("select 1");
 		assertFalse(s.getResultSet().next());
+		
+		s.execute("set autoCommitTxn off");
+		s.execute("set noexec off");
+		s.execute("call proc2(0)");
+		//verify that the block txn was committed because the exception was caught
+		assertEquals(1, tm.txnHistory.size());
+		txn = tm.txnHistory.remove(0);
+		Mockito.verify(txn).commit();
 	}
 
 }

Modified: trunk/runtime/src/test/java/org/teiid/transport/TestCommSockets.java
===================================================================
--- trunk/runtime/src/test/java/org/teiid/transport/TestCommSockets.java	2012-09-26 17:05:51 UTC (rev 4474)
+++ trunk/runtime/src/test/java/org/teiid/transport/TestCommSockets.java	2012-09-26 23:15:59 UTC (rev 4475)
@@ -230,9 +230,10 @@
 		assertEquals(2, stats.objectsRead); // handshake response, logon,
 		assertEquals(1, stats.sockets);
 		conn.cleanUp();
+		assertEquals(1, this.service.getActiveSessionsCount());
 		helpEstablishConnection(false, config, p);
 		conn.selectServerInstance(false);
-		assertEquals(2, this.service.getActiveSessions().size());
+		assertEquals(2, this.service.getActiveSessionsCount());
 		assertTrue(conn.isOpen(1000));
 		stats = listener.getStats();
 		assertEquals(7, stats.objectsRead); // ping (pool test), assert identity, ping (isOpen)

Modified: trunk/test-integration/common/src/test/java/org/teiid/jdbc/FakeServer.java
===================================================================
--- trunk/test-integration/common/src/test/java/org/teiid/jdbc/FakeServer.java	2012-09-26 17:05:51 UTC (rev 4474)
+++ trunk/test-integration/common/src/test/java/org/teiid/jdbc/FakeServer.java	2012-09-26 23:15:59 UTC (rev 4475)
@@ -201,10 +201,6 @@
 		return this.repo.getLiveVDB(vdbName, 1);
 	}
 	
-	public void undeployVDB(String vdbName) {
-		this.repo.removeVDB(vdbName, 1);
-	}
-	
 	public ConnectionImpl createConnection(String embeddedURL) throws Exception {
 		return getDriver().connect(embeddedURL, null);
 	}

Modified: trunk/test-integration/common/src/test/java/org/teiid/systemmodel/TestMetadataUpdates.java
===================================================================
--- trunk/test-integration/common/src/test/java/org/teiid/systemmodel/TestMetadataUpdates.java	2012-09-26 17:05:51 UTC (rev 4474)
+++ trunk/test-integration/common/src/test/java/org/teiid/systemmodel/TestMetadataUpdates.java	2012-09-26 23:15:59 UTC (rev 4475)
@@ -29,7 +29,9 @@
 import java.sql.SQLException;
 import java.sql.Statement;
 
+import org.junit.After;
 import org.junit.AfterClass;
+import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Test;
 import org.mockito.Mockito;
@@ -45,15 +47,29 @@
 @SuppressWarnings("nls")
 public class TestMetadataUpdates {
 	
-	static Connection connection;
+	Connection connection;
     
     static final String VDB = "metadata";
+
+	private static FakeServer server;
     
-	@BeforeClass public static void setUp() throws Exception {
-    	FakeServer server = new FakeServer(true);    	
-    	server.deployVDB(VDB, UnitTestUtil.getTestDataPath() + "/metadata.vdb", new DeployVDBParameter(null, getMetadataRepo()));
-    	connection = server.createConnection("jdbc:teiid:" + VDB); //$NON-NLS-1$ //$NON-NLS-2$		
+	@BeforeClass public static void oneTimeSetUp() throws Exception {
+    	server = new FakeServer(true);    	
     }
+	
+	@AfterClass public static void oneTimeTearDown() throws Exception {
+		server.stop();
+	}
+	
+	@Before public void setup() throws Exception {
+		server.undeployVDB(VDB);
+		server.deployVDB(VDB, UnitTestUtil.getTestDataPath() + "/metadata.vdb", new DeployVDBParameter(null, getMetadataRepo()));
+		connection = server.createConnection("jdbc:teiid:" + VDB); //$NON-NLS-1$ //$NON-NLS-2$		
+	}
+	
+    @After public void tearDown() throws SQLException {
+    	connection.close();
+    }
 
 	private static DefaultMetadataRepository getMetadataRepo() {
 		DefaultMetadataRepository repo = Mockito.mock(DefaultMetadataRepository.class);
@@ -92,10 +108,6 @@
     	return repo;
 	}
     
-    @AfterClass public static void tearDown() throws SQLException {
-    	connection.close();
-    }
-
     @Test public void testViewMetadataRepositoryMerge() throws Exception {
     	Statement s = connection.createStatement();
     	ResultSet rs = s.executeQuery("select * from vw");
@@ -152,7 +164,6 @@
     	assertEquals(2011, rs.getInt(1));
     	
     	assertFalse(s.execute("alter procedure proc as begin select '2012'; end"));
-    	
     	//the sleep is needed to ensure that the plan is invalidated
     	Thread.sleep(100); 
     	



More information about the teiid-commits mailing list