[teiid-commits] teiid SVN: r2395 - in trunk: connectors/translator-ws/src/main/java/org/teiid/translator/ws and 22 other directories.

teiid-commits at lists.jboss.org teiid-commits at lists.jboss.org
Sat Jul 31 18:31:33 EDT 2010


Author: shawkins
Date: 2010-07-31 18:31:31 -0400 (Sat, 31 Jul 2010)
New Revision: 2395

Added:
   trunk/engine/src/main/java/org/teiid/query/optimizer/ProcedurePlanner.java
   trunk/engine/src/main/java/org/teiid/query/processor/BatchedUpdatePlan.java
   trunk/engine/src/main/java/org/teiid/query/processor/proc/Program.java
   trunk/engine/src/main/java/org/teiid/query/processor/proc/ProgramInstruction.java
   trunk/engine/src/test/java/org/teiid/query/optimizer/TestBatchedUpdatePlanner.java
   trunk/engine/src/test/java/org/teiid/query/processor/TestBatchedUpdatePlan.java
Removed:
   trunk/engine/src/main/java/org/teiid/query/optimizer/proc/
   trunk/engine/src/main/java/org/teiid/query/processor/batch/
   trunk/engine/src/main/java/org/teiid/query/processor/program/
   trunk/engine/src/main/java/org/teiid/query/util/XMLFormatConstants.java
   trunk/engine/src/test/java/org/teiid/query/optimizer/batch/
   trunk/engine/src/test/java/org/teiid/query/processor/batch/
Modified:
   trunk/client/src/main/java/org/teiid/jdbc/DatabaseMetaDataImpl.java
   trunk/connectors/translator-ws/src/main/java/org/teiid/translator/ws/WSProcedureExecution.java
   trunk/engine/src/main/java/org/teiid/common/buffer/BufferManager.java
   trunk/engine/src/main/java/org/teiid/common/buffer/SPage.java
   trunk/engine/src/main/java/org/teiid/common/buffer/STree.java
   trunk/engine/src/main/java/org/teiid/common/buffer/impl/BufferManagerImpl.java
   trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPCore.java
   trunk/engine/src/main/java/org/teiid/dqp/internal/process/DataTierManagerImpl.java
   trunk/engine/src/main/java/org/teiid/dqp/internal/process/MetaDataProcessor.java
   trunk/engine/src/main/java/org/teiid/dqp/internal/process/Request.java
   trunk/engine/src/main/java/org/teiid/query/metadata/BasicQueryMetadata.java
   trunk/engine/src/main/java/org/teiid/query/metadata/BasicQueryMetadataWrapper.java
   trunk/engine/src/main/java/org/teiid/query/metadata/QueryMetadataInterface.java
   trunk/engine/src/main/java/org/teiid/query/metadata/TempMetadataAdapter.java
   trunk/engine/src/main/java/org/teiid/query/metadata/TempMetadataID.java
   trunk/engine/src/main/java/org/teiid/query/metadata/TransformationMetadata.java
   trunk/engine/src/main/java/org/teiid/query/optimizer/BatchedUpdatePlanner.java
   trunk/engine/src/main/java/org/teiid/query/optimizer/QueryOptimizer.java
   trunk/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java
   trunk/engine/src/main/java/org/teiid/query/processor/ProcessorDataManager.java
   trunk/engine/src/main/java/org/teiid/query/processor/TempTableDataManager.java
   trunk/engine/src/main/java/org/teiid/query/processor/proc/AssignmentInstruction.java
   trunk/engine/src/main/java/org/teiid/query/processor/proc/BreakInstruction.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/RepeatedInstruction.java
   trunk/engine/src/main/java/org/teiid/query/processor/proc/WhileInstruction.java
   trunk/engine/src/main/java/org/teiid/query/processor/relational/AccessNode.java
   trunk/engine/src/main/java/org/teiid/query/processor/relational/BatchedUpdateNode.java
   trunk/engine/src/main/java/org/teiid/query/processor/relational/DependentProcedureAccessNode.java
   trunk/engine/src/main/java/org/teiid/query/processor/relational/PlanExecutionNode.java
   trunk/engine/src/main/java/org/teiid/query/processor/relational/ProjectIntoNode.java
   trunk/engine/src/main/java/org/teiid/query/processor/relational/SubqueryAwareEvaluator.java
   trunk/engine/src/main/java/org/teiid/query/processor/xml/InitializeDocumentInstruction.java
   trunk/engine/src/main/java/org/teiid/query/processor/xml/RelationalPlanExecutor.java
   trunk/engine/src/main/java/org/teiid/query/processor/xml/XMLPlan.java
   trunk/engine/src/main/java/org/teiid/query/sql/lang/From.java
   trunk/engine/src/main/java/org/teiid/query/sql/symbol/GroupSymbol.java
   trunk/engine/src/main/java/org/teiid/query/tempdata/TempTable.java
   trunk/engine/src/main/java/org/teiid/query/tempdata/TempTableStore.java
   trunk/engine/src/main/java/org/teiid/query/util/CommandContext.java
   trunk/engine/src/test/java/org/teiid/common/buffer/TestSTree.java
   trunk/engine/src/test/java/org/teiid/dqp/internal/process/SimpleQueryProcessorFactory.java
   trunk/engine/src/test/java/org/teiid/dqp/internal/process/multisource/TestMultiSourcePlanToProcessConverter.java
   trunk/engine/src/test/java/org/teiid/query/optimizer/TestOptimizer.java
   trunk/engine/src/test/java/org/teiid/query/processor/FakeDataManager.java
   trunk/engine/src/test/java/org/teiid/query/processor/HardcodedDataManager.java
   trunk/engine/src/test/java/org/teiid/query/processor/TestProcedureRelational.java
   trunk/engine/src/test/java/org/teiid/query/processor/TestTempTables.java
   trunk/engine/src/test/java/org/teiid/query/processor/relational/TestBatchedUpdateNode.java
   trunk/engine/src/test/java/org/teiid/query/processor/relational/TestProjectIntoNode.java
   trunk/engine/src/test/java/org/teiid/query/processor/xml/TestXMLProcessor.java
   trunk/engine/src/test/java/org/teiid/query/unittest/FakeMetadataFactory.java
Log:
TEIID-168 beginning to rough in support for temp tables that are global to the vdb.  also minor cleanups.

Modified: trunk/client/src/main/java/org/teiid/jdbc/DatabaseMetaDataImpl.java
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/DatabaseMetaDataImpl.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/client/src/main/java/org/teiid/jdbc/DatabaseMetaDataImpl.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -263,8 +263,8 @@
         .append(".ProcedureParams as p") //$NON-NLS-1$
         .append(" WHERE UCASE(VDBName)").append(LIKE_ESCAPE)//$NON-NLS-1$
         .append(" AND UCASE(SchemaName)").append(LIKE_ESCAPE)//$NON-NLS-1$
-        .append(" AND UCASE(ProcedureName)") .append(LIKE_ESCAPE) //$NON-NLS-1$
-        .append(" AND UCASE(p.Name) LIKE ?") //$NON-NLS-1$
+        .append(" AND UCASE(ProcedureName)").append(LIKE_ESCAPE) //$NON-NLS-1$
+        .append(" AND UCASE(p.Name)").append(LIKE_ESCAPE) //$NON-NLS-1$
         .append(" ORDER BY PROCEDURE_SCHEM, PROCEDURE_NAME, COLUMN_TYPE, POSITION").toString(); //$NON-NLS-1$
 
     private static final String QUERY_SCHEMAS =

Modified: trunk/connectors/translator-ws/src/main/java/org/teiid/translator/ws/WSProcedureExecution.java
===================================================================
--- trunk/connectors/translator-ws/src/main/java/org/teiid/translator/ws/WSProcedureExecution.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/connectors/translator-ws/src/main/java/org/teiid/translator/ws/WSProcedureExecution.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -85,7 +85,7 @@
         XMLType docObject = (XMLType)arguments.get(2).getArgumentValue().getValue();
         Source source = null;
     	try {
-	        source = converToSource(docObject);
+	        source = convertToSource(docObject);
 	        String endpoint = (String)arguments.get(3).getArgumentValue().getValue();
 	        
 	        if (style == null) {
@@ -149,7 +149,7 @@
 		}
     }
 
-	private StreamSource converToSource(SQLXML xml) throws SQLException {
+	private StreamSource convertToSource(SQLXML xml) throws SQLException {
 		if (xml == null) {
 			return null;
 		}

Modified: trunk/engine/src/main/java/org/teiid/common/buffer/BufferManager.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/common/buffer/BufferManager.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/main/java/org/teiid/common/buffer/BufferManager.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -114,6 +114,6 @@
      */
     int getSchemaSize(List elements);
     
-    STree createSTree(final List elements, String groupName, TupleSourceType tupleSourceType, int keyLength);
+    STree createSTree(final List elements, String groupName, int keyLength);
     
 }

Modified: trunk/engine/src/main/java/org/teiid/common/buffer/SPage.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/common/buffer/SPage.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/main/java/org/teiid/common/buffer/SPage.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -84,23 +84,31 @@
 					return new SearchResult(-previousValues.getTuples().size() - 1, page.prev, previousValues);
 				}
 				if (parent != null && index != 0) {
-					//for non-matches move the previous pointer over to this page
-					SPage childPage = page;
-					List oldKey = null;
-					List newKey = page.stree.extractKey(values.getTuples().get(0));
-					for (Iterator<SearchResult> desc = parent.descendingIterator(); desc.hasNext();) {
-						SearchResult sr = desc.next();
-						int parentIndex = Math.max(0, -sr.index - 2);
-						if (oldKey == null) {
-							oldKey = sr.values.getTuples().set(parentIndex, newKey); 
-						} else if (page.stree.comparator.compare(oldKey, sr.values.getTuples().get(parentIndex)) == 0 ) {
-							sr.values.getTuples().set(parentIndex, newKey);
-						} else {
-							break;
+					page.stree.updateLock.lock();
+					try {
+						index = Collections.binarySearch(values.getTuples(), k, page.stree.comparator);
+						if (index != 0) {
+							//for non-matches move the previous pointer over to this page
+							SPage childPage = page;
+							List oldKey = null;
+							List newKey = page.stree.extractKey(values.getTuples().get(0));
+							for (Iterator<SearchResult> desc = parent.descendingIterator(); desc.hasNext();) {
+								SearchResult sr = desc.next();
+								int parentIndex = Math.max(0, -sr.index - 2);
+								if (oldKey == null) {
+									oldKey = sr.values.getTuples().set(parentIndex, newKey); 
+								} else if (page.stree.comparator.compare(oldKey, sr.values.getTuples().get(parentIndex)) == 0 ) {
+									sr.values.getTuples().set(parentIndex, newKey);
+								} else {
+									break;
+								}
+								sr.page.children.set(parentIndex, childPage);
+								sr.page.setValues(sr.values);
+								childPage = sr.page;
+							}
 						}
-						sr.page.children.set(parentIndex, childPage);
-						sr.page.setValues(sr.values);
-						childPage = sr.page;
+					} finally {
+						page.stree.updateLock.unlock();
 					}
 				}
 			}

Modified: trunk/engine/src/main/java/org/teiid/common/buffer/STree.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/common/buffer/STree.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/main/java/org/teiid/common/buffer/STree.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -29,6 +29,7 @@
 import java.util.List;
 import java.util.Random;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.locks.ReentrantLock;
 
 import org.teiid.common.buffer.SPage.SearchResult;
 import org.teiid.core.TeiidComponentException;
@@ -47,7 +48,7 @@
 	private int mask = 1;
 	private int shift = 1;
 	
-	protected SPage[] header = new SPage[] {new SPage(this, true)};
+	protected volatile SPage[] header = new SPage[] {new SPage(this, true)};
     protected BatchManager keyManager;
     protected BatchManager leafManager;
     protected Comparator comparator;
@@ -56,6 +57,8 @@
     protected String[] types;
     protected String[] keytypes;
     
+    protected ReentrantLock updateLock = new ReentrantLock();
+    
     private AtomicInteger rowCount = new AtomicInteger();
 	
 	public STree(BatchManager manager,

Modified: trunk/engine/src/main/java/org/teiid/common/buffer/impl/BufferManagerImpl.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/common/buffer/impl/BufferManagerImpl.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/main/java/org/teiid/common/buffer/impl/BufferManagerImpl.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -472,7 +472,7 @@
         return tupleBuffer;
     }
     
-    public STree createSTree(final List elements, String groupName, TupleSourceType tupleSourceType, int keyLength) {
+    public STree createSTree(final List elements, String groupName, int keyLength) {
     	String newID = String.valueOf(this.tsId.getAndIncrement());
     	int[] lobIndexes = LobManager.getLobIndexes(elements);
     	BatchManager bm = new BatchManagerImpl(newID, elements.size(), lobIndexes);
@@ -481,7 +481,7 @@
     	for (int i = 1; i < compareIndexes.length; i++) {
 			compareIndexes[i] = i;
 		}
-        LogManager.logDetail(LogConstants.CTX_BUFFER_MGR, "Creating STree:", newID, "of type ", tupleSourceType); //$NON-NLS-1$ //$NON-NLS-2$
+        LogManager.logDetail(LogConstants.CTX_BUFFER_MGR, "Creating STree:", newID); //$NON-NLS-1$ 
     	return new STree(keyManager, bm, new ListNestedSortComparator(compareIndexes), getProcessorBatchSize(), keyLength, TupleBuffer.getTypeNames(elements));
     }
 

Modified: trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPCore.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPCore.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPCore.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -25,7 +25,6 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
@@ -146,10 +145,10 @@
 	
 	static class ClientState {
 		List<RequestID> requests;
-		TempTableStore tempTableStoreImpl;
+		TempTableStore sessionTables;
 		
 		public ClientState(TempTableStore tableStoreImpl) {
-			this.tempTableStoreImpl = tableStoreImpl;
+			this.sessionTables = tableStoreImpl;
 		}
 		
 		public synchronized void addRequest(RequestID requestID) {
@@ -203,7 +202,7 @@
     private int chunkSize = Streamable.STREAMING_BATCH_SIZE_IN_BYTES;
     
 	private Map<RequestID, RequestWorkItem> requests = new ConcurrentHashMap<RequestID, RequestWorkItem>();			
-	private Map<String, ClientState> clientState = Collections.synchronizedMap(new HashMap<String, ClientState>());
+	private Map<String, ClientState> clientState = new ConcurrentHashMap<String, ClientState>();
     private boolean useEntitlements = false;
     
     private int maxActivePlans = DQPConfiguration.DEFAULT_MAX_ACTIVE_PLANS;
@@ -236,14 +235,12 @@
     }
     
     public ClientState getClientState(String key, boolean create) {
-    	synchronized (clientState) {
-    		ClientState state = clientState.get(key);
-    		if (state == null && create) {
-    			state = new ClientState(new TempTableStore(bufferManager, key, null));
-        		clientState.put(key, state);
-    		}
-    		return state;
+		ClientState state = clientState.get(key);
+		if (state == null && create) {
+			state = new ClientState(new TempTableStore(bufferManager, key));
+    		clientState.put(key, state);
 		}
+		return state;
     }
 
     /**
@@ -337,7 +334,7 @@
 	    ClientState state = this.getClientState(workContext.getSessionId(), true);
 	    request.initialize(requestMsg, bufferManager,
 				dataTierMgr, transactionService, processorDebugAllowed,
-				state.tempTableStoreImpl, workContext,
+				state.sessionTables, workContext,
 				connectorManagerRepository, this.useEntitlements);
 		
         ResultsFuture<ResultsMessage> resultsFuture = new ResultsFuture<ResultsMessage>();
@@ -675,8 +672,7 @@
                                             this.bufferService,
                                             this.maxCodeTables,
                                             this.maxCodeRecords,
-                                            this.maxCodeTableRecords);    
-
+                                            this.maxCodeTableRecords); 
 	}
 	
 	public void setBufferService(BufferService service) {

Modified: trunk/engine/src/main/java/org/teiid/dqp/internal/process/DataTierManagerImpl.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/dqp/internal/process/DataTierManagerImpl.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/process/DataTierManagerImpl.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -126,14 +126,14 @@
     	return this.connectorManagerRepository.getConnectorManager(connectorName);
     }
 
-	public TupleSource registerRequest(Object processorId, Command command, String modelName, String connectorBindingId, int nodeID) throws TeiidComponentException, TeiidProcessingException {
-		RequestWorkItem workItem = requestMgr.getRequestWorkItem((RequestID)processorId);
+	public TupleSource registerRequest(CommandContext context, Command command, String modelName, String connectorBindingId, int nodeID) throws TeiidComponentException, TeiidProcessingException {
+		RequestWorkItem workItem = requestMgr.getRequestWorkItem((RequestID)context.getProcessorID());
 		
 		if(CoreConstants.SYSTEM_MODEL.equals(modelName)) {
 			return processSystemQuery(command, workItem.getDqpWorkContext());
 		}
 		
-		AtomicRequestMessage aqr = createRequest(processorId, command, modelName, connectorBindingId, nodeID);
+		AtomicRequestMessage aqr = createRequest(context.getProcessorID(), command, modelName, connectorBindingId, nodeID);
 		ConnectorWork work = getCM(aqr.getConnectorName()).registerRequest(aqr);
         return new DataTierTupleSource(aqr, workItem, work, this);
 	}

Modified: trunk/engine/src/main/java/org/teiid/dqp/internal/process/MetaDataProcessor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/dqp/internal/process/MetaDataProcessor.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/process/MetaDataProcessor.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -43,7 +43,6 @@
 import org.teiid.dqp.internal.process.SessionAwareCache.CacheID;
 import org.teiid.dqp.internal.process.multisource.MultiSourceMetadataWrapper;
 import org.teiid.dqp.message.RequestID;
-import org.teiid.language.SQLConstants.NonReserved;
 import org.teiid.query.analysis.AnalysisRecord;
 import org.teiid.query.metadata.QueryMetadataInterface;
 import org.teiid.query.metadata.SupportConstants;
@@ -121,7 +120,7 @@
             if (workItem != null) {
                 ClientState state = requestManager.getClientState(workContext.getSessionId(), false);
                 if (state != null) {
-                	tempTableStore = state.tempTableStoreImpl;
+                	tempTableStore = state.sessionTables;
                 }
             }
         }
@@ -389,7 +388,7 @@
     }
 
     public Map<Integer, Object> getDefaultColumn(String tableName, String columnName, 
-        Class javaType) {
+        Class<?> javaType) {
             
         Map<Integer, Object> column = new HashMap<Integer, Object>();
         

Modified: trunk/engine/src/main/java/org/teiid/dqp/internal/process/Request.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/dqp/internal/process/Request.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/process/Request.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -28,6 +28,7 @@
 import java.util.Properties;
 import java.util.Set;
 
+import org.teiid.adminapi.impl.VDBMetaData;
 import org.teiid.api.exception.query.QueryMetadataException;
 import org.teiid.api.exception.query.QueryParserException;
 import org.teiid.api.exception.query.QueryPlannerException;
@@ -130,6 +131,7 @@
     protected Command userCommand;
     protected boolean returnsUpdateCount;
     protected boolean useEntitlements;
+	private TempTableStore globalTables;
 
     void initialize(RequestMessage requestMsg,
                               BufferManager bufferManager,
@@ -175,7 +177,18 @@
         this.capabilitiesFinder = new CachedFinder(this.connectorManagerRepo, workContext.getVDB());        
         this.capabilitiesFinder = new TempCapabilitiesFinder(this.capabilitiesFinder);
 
-        metadata = workContext.getVDB().getAttachment(QueryMetadataInterface.class);
+        VDBMetaData vdbMetadata = workContext.getVDB();
+        metadata = vdbMetadata.getAttachment(QueryMetadataInterface.class);
+        globalTables = vdbMetadata.getAttachment(TempTableStore.class);
+        if (globalTables == null) {
+        	synchronized (vdbMetadata) {
+        		globalTables = vdbMetadata.getAttachment(TempTableStore.class);
+        		if (globalTables == null) {
+        			globalTables = new TempTableStore(bufferManager, "SYSTEM"); //$NON-NLS-1$
+        			vdbMetadata.addAttchment(TempTableStore.class, globalTables); 
+        		}
+			}
+        }
 
         if (metadata == null) {
             throw new TeiidComponentException(DQPPlugin.Util.getString("DQPCore.Unable_to_load_metadata_for_VDB_name__{0},_version__{1}", this.vdbName, this.vdbVersion)); //$NON-NLS-1$
@@ -234,7 +247,7 @@
                 this.requestMsg.getShowPlan() != ShowPlan.OFF);
         this.context.setProcessorBatchSize(bufferManager.getProcessorBatchSize());
         this.context.setConnectorBatchSize(bufferManager.getConnectorBatchSize());
-        
+        this.context.setGlobalTableStore(this.globalTables);
         if (multiSourceModels != null) {
             MultiSourcePlanToProcessConverter modifier = new MultiSourcePlanToProcessConverter(
 					metadata, idGenerator, analysisRecord, capabilitiesFinder,
@@ -470,7 +483,7 @@
         
         validateQuery(newCommand);
         
-        CommandContext copy = (CommandContext) commandContext.clone();
+        CommandContext copy = commandContext.clone();
         if (recursionGroup != null) {
         	copy.pushCall(recursionGroup);
         }

Modified: trunk/engine/src/main/java/org/teiid/query/metadata/BasicQueryMetadata.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/metadata/BasicQueryMetadata.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/main/java/org/teiid/query/metadata/BasicQueryMetadata.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -503,5 +503,10 @@
 	public FunctionLibrary getFunctionLibrary() {
 		return null;
 	}
+	
+	@Override
+	public boolean isPrimaryKey(Object metadataID) {
+		return false;
+	}
     
 }

Modified: trunk/engine/src/main/java/org/teiid/query/metadata/BasicQueryMetadataWrapper.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/metadata/BasicQueryMetadataWrapper.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/main/java/org/teiid/query/metadata/BasicQueryMetadataWrapper.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -368,5 +368,10 @@
 	public FunctionLibrary getFunctionLibrary() {
 		return actualMetadata.getFunctionLibrary();
 	}
+	
+	@Override
+	public boolean isPrimaryKey(Object metadataID) {
+		return actualMetadata.isPrimaryKey(metadataID);
+	}
 
 }

Modified: trunk/engine/src/main/java/org/teiid/query/metadata/QueryMetadataInterface.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/metadata/QueryMetadataInterface.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/main/java/org/teiid/query/metadata/QueryMetadataInterface.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -678,4 +678,6 @@
     	throws TeiidComponentException, QueryMetadataException;
 
     FunctionLibrary getFunctionLibrary();
+    
+    boolean isPrimaryKey(Object metadataID);
 }

Modified: trunk/engine/src/main/java/org/teiid/query/metadata/TempMetadataAdapter.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/metadata/TempMetadataAdapter.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/main/java/org/teiid/query/metadata/TempMetadataAdapter.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -692,5 +692,17 @@
     	
     	return this.actualMetadata.isScalarGroup(groupID);
     }
+    
+    @Override
+    public boolean isPrimaryKey(Object metadataID) {
+    	if (metadataID instanceof TempMetadataID) {
+    		TempMetadataID tid = (TempMetadataID)metadataID;
+    		if (tid.getPrimaryKey() != null) {
+    			return true;
+    		}
+    		return false;
+    	}
+    	return this.actualMetadata.isPrimaryKey(metadataID);
+    }
 
 }

Modified: trunk/engine/src/main/java/org/teiid/query/metadata/TempMetadataID.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/metadata/TempMetadataID.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/main/java/org/teiid/query/metadata/TempMetadataID.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -49,7 +49,7 @@
     private boolean isTempTable;
     private Collection<TempMetadataID> accessPatterns;
     private int cardinality = QueryMetadataInterface.UNKNOWN_CARDINALITY;
-    private LRUCache localCache;
+    private LRUCache<Object, Object> localCache;
     private boolean scalarGroup;
     private List<TempMetadataID> primaryKey;
     
@@ -234,7 +234,7 @@
     
     Object setProperty(Object key, Object value) {
 		if (this.localCache == null) {
-			this.localCache = new LRUCache(LOCAL_CACHE_SIZE);
+			this.localCache = new LRUCache<Object, Object>(LOCAL_CACHE_SIZE);
     	}
 		return this.localCache.put(key, value);
     }

Modified: trunk/engine/src/main/java/org/teiid/query/metadata/TransformationMetadata.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/metadata/TransformationMetadata.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/main/java/org/teiid/query/metadata/TransformationMetadata.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -1067,4 +1067,11 @@
 	public FunctionLibrary getFunctionLibrary() {
 		return this.functionLibrary;
 	}
+	
+	@Override
+	public boolean isPrimaryKey(Object metadataID) {
+		ArgCheck.isInstanceOf(KeyRecord.class, metadataID);
+		KeyRecord key = (KeyRecord)metadataID;
+		return key.getType() == org.teiid.metadata.KeyRecord.Type.Primary;
+	}
 }
\ No newline at end of file

Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/BatchedUpdatePlanner.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/BatchedUpdatePlanner.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/BatchedUpdatePlanner.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -38,8 +38,8 @@
 import org.teiid.query.optimizer.capabilities.SourceCapabilities;
 import org.teiid.query.optimizer.capabilities.SourceCapabilities.Capability;
 import org.teiid.query.optimizer.relational.rules.CapabilitiesUtil;
+import org.teiid.query.processor.BatchedUpdatePlan;
 import org.teiid.query.processor.ProcessorPlan;
-import org.teiid.query.processor.batch.BatchedUpdatePlan;
 import org.teiid.query.processor.relational.BatchedUpdateNode;
 import org.teiid.query.processor.relational.ProjectNode;
 import org.teiid.query.processor.relational.RelationalPlan;

Copied: trunk/engine/src/main/java/org/teiid/query/optimizer/ProcedurePlanner.java (from rev 2390, trunk/engine/src/main/java/org/teiid/query/optimizer/proc/ProcedurePlanner.java)
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/ProcedurePlanner.java	                        (rev 0)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/ProcedurePlanner.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -0,0 +1,325 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.query.optimizer;
+
+import java.util.Map;
+
+import org.teiid.api.exception.query.QueryMetadataException;
+import org.teiid.api.exception.query.QueryPlannerException;
+import org.teiid.core.TeiidComponentException;
+import org.teiid.core.id.IDGenerator;
+import org.teiid.core.util.Assertion;
+import org.teiid.query.analysis.AnalysisRecord;
+import org.teiid.query.execution.QueryExecPlugin;
+import org.teiid.query.metadata.QueryMetadataInterface;
+import org.teiid.query.optimizer.capabilities.CapabilitiesFinder;
+import org.teiid.query.processor.ProcessorPlan;
+import org.teiid.query.processor.proc.AssignmentInstruction;
+import org.teiid.query.processor.proc.BreakInstruction;
+import org.teiid.query.processor.proc.ContinueInstruction;
+import org.teiid.query.processor.proc.CreateCursorResultSetInstruction;
+import org.teiid.query.processor.proc.ErrorInstruction;
+import org.teiid.query.processor.proc.ExecDynamicSqlInstruction;
+import org.teiid.query.processor.proc.IfInstruction;
+import org.teiid.query.processor.proc.LoopInstruction;
+import org.teiid.query.processor.proc.ProcedurePlan;
+import org.teiid.query.processor.proc.Program;
+import org.teiid.query.processor.proc.ProgramInstruction;
+import org.teiid.query.processor.proc.WhileInstruction;
+import org.teiid.query.sql.lang.Command;
+import org.teiid.query.sql.lang.DynamicCommand;
+import org.teiid.query.sql.lang.ProcedureContainer;
+import org.teiid.query.sql.lang.StoredProcedure;
+import org.teiid.query.sql.lang.TranslatableProcedureContainer;
+import org.teiid.query.sql.proc.AssignmentStatement;
+import org.teiid.query.sql.proc.Block;
+import org.teiid.query.sql.proc.CommandStatement;
+import org.teiid.query.sql.proc.CreateUpdateProcedureCommand;
+import org.teiid.query.sql.proc.IfStatement;
+import org.teiid.query.sql.proc.LoopStatement;
+import org.teiid.query.sql.proc.RaiseErrorStatement;
+import org.teiid.query.sql.proc.Statement;
+import org.teiid.query.sql.proc.WhileStatement;
+import org.teiid.query.sql.symbol.Expression;
+import org.teiid.query.sql.symbol.ScalarSubquery;
+import org.teiid.query.sql.visitor.CommandCollectorVisitor;
+import org.teiid.query.util.CommandContext;
+
+
+/**
+ * <p> This prepares an {@link org.teiid.query.processor.proc.ProcedurePlan ProcedurePlan} from
+ * a CreateUpdateProcedureCommand {@link org.teiid.query.sql.proc.CreateUpdateProcedureCommand CreateUpdateProcedureCommand}.
+ * </p>
+ */
+public final class ProcedurePlanner implements CommandPlanner {
+	
+	/**
+	 * <p>Produce a ProcessorPlan for the CreateUpdateProcedureCommand on the current node
+	 * of the CommandTreeNode, the procedure plan construction involves using the child
+	 * processor plans.</p>
+	 * @param metadata source of metadata
+	 * @param debug whether or not to generate verbose debug output during planning
+	 * @return ProcessorPlan This processorPlan is a <code>ProcedurePlan</code>
+     * @throws QueryPlannerException indicating a problem in planning
+     * @throws QueryMetadataException indicating an exception in accessing the metadata
+     * @throws TeiidComponentException indicating an unexpected exception
+	 */
+	public ProcessorPlan optimize(Command procCommand, IDGenerator idGenerator, QueryMetadataInterface metadata, CapabilitiesFinder capFinder, AnalysisRecord analysisRecord, CommandContext context)
+	throws QueryPlannerException, QueryMetadataException, TeiidComponentException {
+
+        boolean debug = analysisRecord.recordDebug();
+        if(debug) {
+            analysisRecord.println("\n####################################################"); //$NON-NLS-1$
+            analysisRecord.println("PROCEDURE COMMAND: " + procCommand); //$NON-NLS-1$
+        }
+
+        Assertion.isInstanceOf(procCommand, CreateUpdateProcedureCommand.class, "Wrong command type"); //$NON-NLS-1$
+
+        if(debug) {
+            analysisRecord.println("OPTIMIZING SUB-COMMANDS: "); //$NON-NLS-1$
+        }
+        
+        for (Command command : CommandCollectorVisitor.getCommands(procCommand)) {
+        	if (!(command instanceof DynamicCommand)) {
+        		command.setProcessorPlan(QueryOptimizer.optimizePlan(command, metadata, idGenerator, capFinder, analysisRecord, context));
+        	}
+        }
+
+        Block block = ((CreateUpdateProcedureCommand) procCommand).getBlock();
+
+		Program programBlock = planBlock(((CreateUpdateProcedureCommand)procCommand), block, metadata, debug, idGenerator, capFinder, analysisRecord, context);
+
+        if(debug) {
+            analysisRecord.println("\n####################################################"); //$NON-NLS-1$
+        }
+
+        // create plan from program and initialized environment
+        ProcedurePlan plan = new ProcedurePlan(programBlock);
+        
+        // propagate procedure parameters to the plan to allow runtime type checking
+        ProcedureContainer container = (ProcedureContainer)((CreateUpdateProcedureCommand) procCommand).getUserCommand();
+        
+        if (container != null) {
+        	if (container instanceof StoredProcedure) {
+        		plan.setRequiresTransaction(container.getUpdateCount() > 0);
+        	}
+            Map params = container.getProcedureParameters();
+            plan.setParams(params);
+            plan.setMetadata(metadata);
+            if (container instanceof TranslatableProcedureContainer) {
+            	plan.setImplicitParams(((TranslatableProcedureContainer)container).getImplicitParams());
+            }
+        }
+        
+        plan.setUpdateProcedure(((CreateUpdateProcedureCommand)procCommand).isUpdateProcedure());
+        plan.setOutputElements(((CreateUpdateProcedureCommand)procCommand).getProjectedSymbols());
+        
+        if(debug) {
+            analysisRecord.println("####################################################"); //$NON-NLS-1$
+            analysisRecord.println("PROCEDURE PLAN :"+plan); //$NON-NLS-1$
+            analysisRecord.println("####################################################"); //$NON-NLS-1$
+        }
+
+        return plan;
+	}
+
+	/**
+	 * <p> Plan a {@link Block} object, recursively plan each statement in the given block and
+	 * add the resulting {@link ProgramInstruction} a new {@link Program} for the block.</p>
+	 * @param block The <code>Block</code> to be planned
+	 * @param metadata Metadata used during planning
+	 * @param childNodes list of CommandTreeNode objects that contain the ProcessorPlans of the child nodes of this procedure
+	 * @param debug Boolean detemining if procedure plan needs to be printed for debug purposes
+	 * @param analysisRecord TODO
+	 * @return A Program resulting in the block planning
+	 * @throws QueryPlannerException if invalid statement is encountered in the block
+	 * @throws QueryMetadataException if there is an error accessing metadata
+	 * @throws TeiidComponentException if unexpected error occurs
+	 */
+    private Program planBlock(CreateUpdateProcedureCommand parentProcCommand, Block block, QueryMetadataInterface metadata, boolean debug, IDGenerator idGenerator, CapabilitiesFinder capFinder, AnalysisRecord analysisRecord, CommandContext context)
+        throws QueryPlannerException, QueryMetadataException, TeiidComponentException {
+
+        // Generate program and add instructions
+        // this program represents the block on the procedure
+        // instruction in the program would correspond to statements in the block
+        Program programBlock = new Program();
+
+		// plan each statement in the block
+        for (Statement statement : block.getStatements()) {
+			Object instruction = planStatement(parentProcCommand, statement, metadata, debug, idGenerator, capFinder, analysisRecord, context);
+            if(instruction instanceof ProgramInstruction){
+                programBlock.addInstruction((ProgramInstruction)instruction);
+            }else{
+                //an array of ProgramInstruction
+                ProgramInstruction[] insts = (ProgramInstruction[])instruction;
+                for(int i=0; i<insts.length; i++){
+			        programBlock.addInstruction(insts[i]);
+                }
+            }
+        }
+
+        return programBlock;
+    }
+
+	/**
+	 * <p> Plan a {@link Statement} object, depending on the type of the statement construct the appropriate
+	 * {@link ProgramInstruction} return it to added to a {@link Program}. If the statement references a
+	 * <code>Command</code>, it looks up the child CommandTreeNodes to get approproiate child's ProcessrPlan
+	 * and uses it for constructing the necessary instruction.</p>
+	 * @param statement The statement to be planned
+	 * @param metadata Metadata used during planning
+	 * @param childNodes list of CommandTreeNode objects that contain the ProcessorPlans of the child nodes of this procedure
+	 * @param debug Boolean detemining if procedure plan needs to be printed for debug purposes
+	 * @param analysisRecord TODO
+	 * @return An array containing index of the next child to be accessesd and the ProgramInstruction resulting
+	 * in the statement planning
+	 * @throws QueryPlannerException if invalid statement is encountered
+	 * @throws QueryMetadataException if there is an error accessing metadata
+	 * @throws TeiidComponentException if unexpected error occurs
+	 */
+    private Object planStatement(CreateUpdateProcedureCommand parentProcCommand, Statement statement, QueryMetadataInterface metadata, boolean debug, IDGenerator idGenerator, CapabilitiesFinder capFinder, AnalysisRecord analysisRecord, CommandContext context)
+        throws QueryPlannerException, QueryMetadataException, TeiidComponentException {
+
+		int stmtType = statement.getType();
+		// object array containing updated child index and the process instruction
+		//Object array[] = new Object[2];
+		// program instr resulting in planning this statement
+		Object instruction = null;
+		switch(stmtType) {
+			case Statement.TYPE_ASSIGNMENT:
+            case Statement.TYPE_DECLARE:
+            {
+                AssignmentInstruction assignInstr = new AssignmentInstruction();
+                instruction = assignInstr;
+                
+                AssignmentStatement assignStmt = (AssignmentStatement)statement;
+                
+                assignInstr.setVariable(assignStmt.getVariable());
+                
+				if(assignStmt.hasCommand()) {
+					assignInstr.setExpression(new ScalarSubquery(assignStmt.getCommand()));
+				} else if (assignStmt.hasExpression()) {
+					Expression asigExpr = assignStmt.getExpression();
+                    assignInstr.setExpression(asigExpr);
+				}
+                if(debug) {
+                	analysisRecord.println("\tASSIGNMENT\n" + statement); //$NON-NLS-1$
+                }
+				break;
+            }
+            case Statement.TYPE_ERROR:
+            {
+            	ErrorInstruction error = new ErrorInstruction();
+            	instruction = error;
+            	RaiseErrorStatement res = (RaiseErrorStatement)statement;
+                
+				if(res.hasCommand()) {
+					error.setExpression(new ScalarSubquery(res.getCommand()));
+				} else if (res.hasExpression()) {
+					Expression asigExpr = res.getExpression();
+					error.setExpression(asigExpr);
+				}
+                if(debug) {
+                	analysisRecord.println("\tERROR STATEMENT:\n" + statement); //$NON-NLS-1$ 
+                }
+            	break;
+            }
+			case Statement.TYPE_COMMAND:
+            {
+				CommandStatement cmdStmt = (CommandStatement) statement;
+                Command command = cmdStmt.getCommand();
+				ProcessorPlan commandPlan = cmdStmt.getCommand().getProcessorPlan();                
+                
+				if (command.getType() == Command.TYPE_DYNAMIC){
+					instruction = new ExecDynamicSqlInstruction(parentProcCommand,((DynamicCommand)command), metadata, idGenerator, capFinder );
+				}else{
+					instruction = new CreateCursorResultSetInstruction(CreateCursorResultSetInstruction.RS_NAME, commandPlan);
+				}
+                
+				if(debug) {
+					analysisRecord.println("\tCOMMAND STATEMENT:\n " + statement); //$NON-NLS-1$
+					analysisRecord.println("\t\tSTATEMENT COMMAND PROCESS PLAN:\n " + commandPlan); //$NON-NLS-1$
+				}
+				break;
+            }
+			case Statement.TYPE_IF:
+            {
+				IfStatement ifStmt = (IfStatement)statement;
+				Program ifProgram = planBlock(parentProcCommand, ifStmt.getIfBlock(), metadata, debug, idGenerator, capFinder, analysisRecord, context);
+				Program elseProgram = null;
+				if(ifStmt.hasElseBlock()) {
+					elseProgram = planBlock(parentProcCommand, ifStmt.getElseBlock(), metadata, debug, idGenerator, capFinder, analysisRecord, context);
+				}
+				instruction = new IfInstruction(ifStmt.getCondition(), ifProgram, elseProgram);
+				if(debug) {
+					analysisRecord.println("\tIF STATEMENT:\n" + statement); //$NON-NLS-1$
+				}
+				break;
+            }
+            case Statement.TYPE_BREAK:
+            {
+                if(debug) {
+                	analysisRecord.println("\tBREAK STATEMENT:\n" + statement); //$NON-NLS-1$
+                }
+                instruction = new BreakInstruction();
+                break;
+            }
+            case Statement.TYPE_CONTINUE:
+            {
+                if(debug) {
+                	analysisRecord.println("\tCONTINUE STATEMENT:\n" + statement); //$NON-NLS-1$
+                }
+                instruction = new ContinueInstruction();
+                break;
+            }
+            case Statement.TYPE_LOOP:
+            {
+                LoopStatement loopStmt = (LoopStatement)statement;
+                if(debug) {
+                	analysisRecord.println("\tLOOP STATEMENT:\n" + statement); //$NON-NLS-1$
+                }
+                String rsName = loopStmt.getCursorName();
+
+                ProcessorPlan commandPlan = loopStmt.getCommand().getProcessorPlan();
+
+                Program loopProgram = planBlock(parentProcCommand, loopStmt.getBlock(), metadata, debug, idGenerator, capFinder, analysisRecord, context);
+                instruction = new LoopInstruction(loopProgram, rsName, commandPlan);
+                break;
+            }
+            case Statement.TYPE_WHILE:
+            {
+                WhileStatement whileStmt = (WhileStatement)statement;
+                Program whileProgram = planBlock(parentProcCommand, whileStmt.getBlock(), metadata, debug, idGenerator, capFinder, analysisRecord, context);
+                if(debug) {
+                	analysisRecord.println("\tWHILE STATEMENT:\n" + statement); //$NON-NLS-1$
+                }
+                instruction = new WhileInstruction(whileProgram, whileStmt.getCondition());
+                break;
+            }
+			default:
+	        	throw new QueryPlannerException(QueryExecPlugin.Util.getString("ProcedurePlanner.bad_stmt", stmtType)); //$NON-NLS-1$
+		}
+		return instruction;
+    }
+        
+} // END CLASS

Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/QueryOptimizer.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/QueryOptimizer.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/QueryOptimizer.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -37,7 +37,6 @@
 import org.teiid.query.metadata.TempMetadataAdapter;
 import org.teiid.query.metadata.TempMetadataStore;
 import org.teiid.query.optimizer.capabilities.CapabilitiesFinder;
-import org.teiid.query.optimizer.proc.ProcedurePlanner;
 import org.teiid.query.optimizer.relational.RelationalPlanner;
 import org.teiid.query.optimizer.xml.XMLPlanner;
 import org.teiid.query.processor.ProcessorPlan;
@@ -107,7 +106,9 @@
 				if (command.getType() == Command.TYPE_QUERY && command instanceof Query && QueryResolver.isXMLQuery((Query)command, metadata)) {
 					result = XML_PLANNER.optimize(command, idGenerator, metadata, capFinder, analysisRecord, context);
 				} else {
-					result = new RelationalPlanner().optimize(command, idGenerator, metadata, capFinder, analysisRecord, context);
+					RelationalPlanner planner = new RelationalPlanner();
+					planner.initialize(command, idGenerator, metadata, capFinder, analysisRecord, context);
+					result = planner.optimize(command);
 				}
 			} catch (QueryResolverException e) {
 				throw new TeiidRuntimeException(e);

Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -35,6 +35,7 @@
 import org.teiid.api.exception.query.QueryParserException;
 import org.teiid.api.exception.query.QueryPlannerException;
 import org.teiid.api.exception.query.QueryResolverException;
+import org.teiid.api.exception.query.QueryValidatorException;
 import org.teiid.client.plan.Annotation;
 import org.teiid.client.plan.Annotation.Priority;
 import org.teiid.core.TeiidComponentException;
@@ -50,7 +51,7 @@
 import org.teiid.query.metadata.QueryMetadataInterface;
 import org.teiid.query.metadata.TempMetadataAdapter;
 import org.teiid.query.metadata.TempMetadataID;
-import org.teiid.query.optimizer.CommandPlanner;
+import org.teiid.query.metadata.TempMetadataStore;
 import org.teiid.query.optimizer.QueryOptimizer;
 import org.teiid.query.optimizer.capabilities.CapabilitiesFinder;
 import org.teiid.query.optimizer.relational.plantree.NodeConstants;
@@ -112,7 +113,7 @@
  * to  produce a
  * {@link org.teiid.query.processor.relational.RelationalPlan RelationalPlan}.
  */
-public class RelationalPlanner implements CommandPlanner {
+public class RelationalPlanner {
 	
 	private AnalysisRecord analysisRecord;
 	private Command parentCommand;
@@ -122,18 +123,13 @@
 	private QueryMetadataInterface metadata;
 	private PlanHints hints = new PlanHints();
 	private Option option;
-
+	
     public ProcessorPlan optimize(
-        Command command,
-        IDGenerator idGenerator,
-        QueryMetadataInterface metadata,
-        CapabilitiesFinder capFinder,
-        AnalysisRecord analysisRecord, CommandContext context)
+        Command command)
         throws
             QueryPlannerException,
             QueryMetadataException,
             TeiidComponentException {
-    	initialize(command, idGenerator, metadata, capFinder, analysisRecord, context);
 
         boolean debug = analysisRecord.recordDebug();
 		if(debug) {
@@ -900,11 +896,12 @@
         QueryNode qnode = null;
         
         Object metadataID = virtualGroup.getMetadataID();
-        boolean noCache = false;
+        boolean noCache = isNoCacheGroup(metadata, metadataID, option);
         boolean isMaterializedGroup = metadata.hasMaterialization(metadataID);
         String cacheString = "select"; //$NON-NLS-1$
+        String groupName = metadata.getFullName(metadataID);
+        
         if( isMaterializedGroup) {
-            noCache = isNoCacheGroup(metadata, metadataID, option);
         	if(noCache){
         		//not use cache
         		qnode = metadata.getVirtualPlan(metadataID);
@@ -912,7 +909,6 @@
         		recordMaterializationTableAnnotation(virtualGroup, analysisRecord, matTableName, "SimpleQueryResolver.materialized_table_not_used"); //$NON-NLS-1$
         	}else{
                 // Default query for a materialized group - go to cached table
-                String groupName = metadata.getFullName(metadataID);
                 String matTableName = metadata.getFullName(metadata.getMaterialization(metadataID));
                 qnode = new QueryNode(groupName, "SELECT * FROM " + matTableName); //$NON-NLS-1$
                 cacheString = "matview"; //$NON-NLS-1$
@@ -923,19 +919,74 @@
             qnode = metadata.getVirtualPlan(metadataID);            
         }
 
-        Command result = (Command)metadata.getFromMetadataCache(virtualGroup.getMetadataID(), "transformation/" + cacheString); //$NON-NLS-1$
+        Command result = getCommand(virtualGroup, qnode, cacheString, metadata);   
+        if (!isMaterializedGroup && result.isCache()) {
+        	result = handleCacheHint(virtualGroup, groupName, noCache, result);
+        }
+        return QueryRewriter.rewrite(result, metadata, context);
+    }
+
+	private Command getCommand(GroupSymbol virtualGroup, QueryNode qnode,
+			String cacheString, QueryMetadataInterface qmi) throws TeiidComponentException,
+			QueryMetadataException, QueryResolverException,
+			QueryValidatorException {
+		Command result = (Command)qmi.getFromMetadataCache(virtualGroup.getMetadataID(), "transformation/" + cacheString); //$NON-NLS-1$
         if (result != null) {
         	result = (Command)result.clone();
         } else {
         	//parse, resolve, validate
-        	result = convertToSubquery(qnode, metadata);
-	        QueryResolver.resolveCommand(result, Collections.EMPTY_MAP, metadata, analysisRecord);
-	        Request.validateWithVisitor(new ValidationVisitor(), metadata, result);
-	        metadata.addToMetadataCache(virtualGroup.getMetadataID(), "transformation/" + cacheString, result.clone()); //$NON-NLS-1$
-        }        
-        return QueryRewriter.rewrite(result, metadata, context);
-    }
+        	result = convertToSubquery(qnode, qmi);
+	        QueryResolver.resolveCommand(result, Collections.EMPTY_MAP, qmi, analysisRecord);
+	        Request.validateWithVisitor(new ValidationVisitor(), qmi, result);
+	        qmi.addToMetadataCache(virtualGroup.getMetadataID(), "transformation/" + cacheString, result.clone()); //$NON-NLS-1$
+        }
+		return result;
+	}
 
+	private Command handleCacheHint(GroupSymbol virtualGroup, String name, boolean noCache, Command result)
+			throws TeiidComponentException, QueryMetadataException, QueryResolverException, QueryValidatorException {
+		TempMetadataStore store = context.getGlobalTableStore().getMetadataStore();
+		String matTableName = "#MAT_" + name; //$NON-NLS-1$
+		TempMetadataID id = store.getTempGroupID(matTableName);
+		//define the table preserving the primary key
+		if (id == null) {
+			synchronized (store) {
+				id = store.getTempGroupID(matTableName);
+				if (id == null) {
+					//TODO: this could be done with a generated create
+					id = store.addTempGroup(matTableName, result.getProjectedSymbols(), false, true);
+					
+					//primary key
+					Collection keys = metadata.getUniqueKeysInGroup(virtualGroup.getMetadataID());
+					for (Object object : keys) {
+						if (metadata.isPrimaryKey(object)) {
+							List cols = metadata.getElementIDsInKey(object);
+							ArrayList<TempMetadataID> primaryKey = new ArrayList<TempMetadataID>(cols.size());
+							for (Object coldId : cols) {
+								int pos = metadata.getPosition(coldId) - 1;
+								primaryKey.add(id.getElements().get(pos));
+							}
+							break;
+						}
+					}
+					//version column?
+					
+					//add timestamp?
+				}
+			}
+		}
+		if (noCache) {
+			//TODO: update the table
+			return result;
+		} 
+/*		QueryMetadataInterface qmi = new TempMetadataAdapter(metadata, context.getGlobalTableStore().getMetadataStore());
+		QueryNode qn = new QueryNode(virtualGroup.getName(), "select * from " + matTableName); //$NON-NLS-1$
+		Query query = (Query)getCommand(virtualGroup, qn, "matview", qmi); //$NON-NLS-1$
+		query.getFrom().getGroups().get(0).setGlobalTable(true);
+		return query;*/
+		return result;
+	}
+
     public static boolean isNoCacheGroup(QueryMetadataInterface metadata,
                                           Object metadataID,
                                           Option option) throws QueryMetadataException,

Copied: trunk/engine/src/main/java/org/teiid/query/processor/BatchedUpdatePlan.java (from rev 2390, trunk/engine/src/main/java/org/teiid/query/processor/batch/BatchedUpdatePlan.java)
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/BatchedUpdatePlan.java	                        (rev 0)
+++ trunk/engine/src/main/java/org/teiid/query/processor/BatchedUpdatePlan.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -0,0 +1,241 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.query.processor;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.teiid.client.plan.PlanNode;
+import org.teiid.common.buffer.BlockedException;
+import org.teiid.common.buffer.BufferManager;
+import org.teiid.common.buffer.TupleBatch;
+import org.teiid.core.TeiidComponentException;
+import org.teiid.core.TeiidProcessingException;
+import org.teiid.query.sql.lang.Command;
+import org.teiid.query.sql.util.VariableContext;
+import org.teiid.query.util.CommandContext;
+
+
+
+/** 
+ * Plan for execution for a batched update command. The plan executes the child plans of the
+ * individual commands in order.
+ * 
+ * If variableContexts are provided, then this is a bulk update where all plans are the same object.
+ * 
+ * @since 4.2
+ */
+public class BatchedUpdatePlan extends ProcessorPlan {
+    
+    /** Array that holds the child update plans */
+    private ProcessorPlan[] updatePlans;
+    /** */
+    private boolean[] planOpened;
+    /** Array that holds the update counts for each command in this batch */
+    private List[] updateCounts;
+    /** The position of the plan currently being executed */
+    private int planIndex = 0;
+    /** The position of the command for which the update count is being retrieved */
+    private int commandIndex = 0;
+    
+    private List<VariableContext> contexts; //only set for bulk updates
+    
+    /**
+     *  
+     * @param childPlans the child update plans for this batch
+     * @param commandsInBatch The total number of commands in this batch. This does not always equal the number of plans if some
+     * commands have been batched together.
+     * @since 4.2
+     */
+    public BatchedUpdatePlan(List childPlans, int commandsInBatch, List<VariableContext> contexts) {
+        this.updatePlans = (ProcessorPlan[])childPlans.toArray(new ProcessorPlan[childPlans.size()]);
+        this.planOpened = new boolean[updatePlans.length];
+        this.updateCounts = new List[commandsInBatch];
+        this.contexts = contexts;
+    }
+
+    /** 
+     * @see java.lang.Object#clone()
+     * @since 4.2
+     */
+    public BatchedUpdatePlan clone() {
+        List<ProcessorPlan> clonedPlans = new ArrayList<ProcessorPlan>(updatePlans.length);
+        
+        clonedPlans.add(updatePlans[0].clone());
+        for (int i = 1; i <updatePlans.length; i++) {
+        	if (contexts == null) {
+                clonedPlans.add(updatePlans[1].clone());        		
+        	} else {
+        		clonedPlans.add(clonedPlans.get(0));
+        	}
+        }
+        return new BatchedUpdatePlan(clonedPlans, updateCounts.length, contexts);
+    }
+
+    /** 
+     * @see org.teiid.query.processor.ProcessorPlan#initialize(org.teiid.query.util.CommandContext, org.teiid.query.processor.ProcessorDataManager, org.teiid.common.buffer.BufferManager)
+     * @since 4.2
+     */
+    public void initialize(CommandContext context, ProcessorDataManager dataMgr, BufferManager bufferMgr) {
+    	context = context.clone();
+    	context.setVariableContext(new VariableContext()); //start a new root variable context
+    	this.setContext(context);
+        // Initialize all the child plans
+        for (int i = 0; i < getPlanCount(); i++) {
+            updatePlans[i].initialize(context, dataMgr, bufferMgr);
+        }
+    }
+    
+    /** 
+     * @see org.teiid.query.processor.ProcessorPlan#getOutputElements()
+     * @since 4.2
+     */
+    public List getOutputElements() {
+        return Command.getUpdateCommandSymbol();
+    }
+
+    /** 
+     * @see org.teiid.query.processor.ProcessorPlan#open()
+     * @since 4.2
+     */
+    public void open() throws TeiidComponentException, TeiidProcessingException {
+        // It's ok to open() the first plan, as it is not dependent on any prior commands.
+        // See note for defect 16166 in the nextBatch() method.
+       openPlan();
+    }
+
+    /** 
+     * @see org.teiid.query.processor.ProcessorPlan#nextBatch()
+     * @since 4.2
+     */
+    public TupleBatch nextBatch() throws BlockedException, TeiidComponentException, TeiidProcessingException {
+        for (;planIndex < updatePlans.length; planIndex++) {
+            if (!planOpened[planIndex]) { // Open the plan only once
+                /* Defect 16166
+                 * Some commands in a batch may depend on updates by previous commands in the same batch. A call
+                 * to open() usually submits an atomic command, so calling open() on all the child plans at the same time
+                 * will mean that the datasource may not be in the state expected by a later command within the batch. So,
+                 * for a batch of commands, we only open() a later plan when we are finished with the previous plan to
+                 * guarantee that the commands in the previous plan are completed before the commands in any subsequent
+                 * plans are executed.
+                 */
+            	openPlan();
+            }
+            // Execute nextBatch() on each plan in sequence
+            List<List> currentBatch = updatePlans[planIndex].nextBatch().getTuples(); // Can throw BlockedException
+            for (int i = 0; i < currentBatch.size(); i++, commandIndex++) {
+                updateCounts[commandIndex] = currentBatch.get(i);
+            }
+            
+            // since we are done with the plan explicitly close it.
+            updatePlans[planIndex].close();
+        }
+        // Add tuples to current batch
+        TupleBatch batch = new TupleBatch(1, updateCounts);
+        batch.setTerminationFlag(true);
+        return batch;
+    }
+
+	private void openPlan() throws TeiidComponentException,
+			TeiidProcessingException {
+		if (this.contexts != null && !this.contexts.isEmpty()) {
+			CommandContext context = updatePlans[planIndex].getContext();
+			context.getVariableContext().clear();
+			VariableContext currentValues = this.contexts.get(planIndex);
+			context.getVariableContext().putAll(currentValues); 
+		}
+		updatePlans[planIndex].reset();
+		updatePlans[planIndex].open();
+		planOpened[planIndex] = true;
+	}
+
+    /** 
+     * @see org.teiid.query.processor.ProcessorPlan#close()
+     * @since 4.2
+     */
+    public void close() throws TeiidComponentException {
+        // if the plan opened but the atomic request got cancelled then close the last plan node.
+        if (planIndex < updatePlans.length && planOpened[planIndex]) {
+            updatePlans[planIndex].close();
+        }
+    }
+
+    
+    /** 
+     * @see org.teiid.query.processor.ProcessorPlan#reset()
+     * @since 4.2
+     */
+    public void reset() {
+        super.reset();
+        for (int i = 0; i < updatePlans.length; i++) {
+            updatePlans[i].reset();
+            planOpened[i] = false;
+        }
+        for (int i = 0; i < updateCounts.length; i++) {
+            updateCounts[i] = null;
+        }
+        planIndex = 0;
+        commandIndex = 0;
+    }
+
+    public PlanNode getDescriptionProperties() {
+    	PlanNode props = super.getDescriptionProperties();
+        for (int i = 0; i < getPlanCount(); i++) {
+            props.addProperty("Batch Plan " + i, updatePlans[i].getDescriptionProperties()); //$NON-NLS-1$
+        }
+        return props;
+    }
+    
+    public String toString() {
+        StringBuffer val = new StringBuffer("BatchedUpdatePlan {\n"); //$NON-NLS-1$
+        for (int i = 0; i < getPlanCount(); i++) {
+            val.append(updatePlans[i])
+               .append("\n"); //$NON-NLS-1$
+        }
+        val.append("}\n"); //$NON-NLS-1$
+        return val.toString();
+    }
+
+	private int getPlanCount() {
+		return (contexts != null?1:updatePlans.length);
+	}
+
+    /**
+     * Returns the child plans for this batch. Used primarily for unit tests. 
+     * @return
+     * @since 4.2
+     */
+    public List getUpdatePlans() {
+        return Arrays.asList(updatePlans);
+    }
+    
+    @Override
+    public boolean requiresTransaction(boolean transactionalReads) {
+		if (updatePlans.length == 1) {
+			return updatePlans[0].requiresTransaction(transactionalReads);
+		}
+		return true;
+    }
+
+}

Modified: trunk/engine/src/main/java/org/teiid/query/processor/ProcessorDataManager.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/ProcessorDataManager.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/main/java/org/teiid/query/processor/ProcessorDataManager.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -32,7 +32,7 @@
 
 public interface ProcessorDataManager {
 
-	TupleSource registerRequest(Object processorId, Command command, String modelName, String connectorBindingId, int nodeID)
+	TupleSource registerRequest(CommandContext context, Command command, String modelName, String connectorBindingId, int nodeID)
 		throws TeiidComponentException, TeiidProcessingException;
 	
     /**

Modified: trunk/engine/src/main/java/org/teiid/query/processor/TempTableDataManager.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/TempTableDataManager.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/main/java/org/teiid/query/processor/TempTableDataManager.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -32,10 +32,7 @@
 
 
 /**
- * This proxy ProcessorDataManager is used during XML query processing to handle temporary groups
- * in the document model.  Temp groups are materialized during processing, and their tuple sources
- * are cached, so this proxy shortcuts the need to go to the DataTierManager and immediately
- * returns the tuple source (synchronously) if a temp group's source is what's being requested.
+ * This proxy ProcessorDataManager is used to handle temporary tables.
  */
 public class TempTableDataManager implements ProcessorDataManager {
 
@@ -45,38 +42,28 @@
     /**
      * Constructor takes the "real" ProcessorDataManager that this object will be a proxy to,
      * and will pass most calls through to transparently.  Only when a request is registered for
-     * a temp group will this proxy do it's thing.  A ProcessorEnvironment is needed to to 
-     * access cached information about temp groups
+     * a temp group will this proxy do it's thing.
      * @param processorDataManager the real ProcessorDataManager that this object is a proxy to
-     * @param env a ProcessorEnvironment implementation
      */
     public TempTableDataManager(ProcessorDataManager processorDataManager, TempTableStore tempTableStore){
         this.processorDataManager = processorDataManager;
         this.tempTableStore = tempTableStore;
     }
 
-	/**
-     * This is the magic method.  If the command is selecting from a temporary group, that 
-     * temporary groups tuple source (which is cached in the ProcessorEnvironment) will
-     * be retrieved and immediately (synchronously) delivered to the QueryProcessor.
-     * If a temp group is <i>not</i> being selected from, then this request will be
-     * passed through to the underlying ProcessorDataManager.
-	 * @throws TeiidProcessingException 
-	 */
 	public TupleSource registerRequest(
-		Object processorID,
+		CommandContext context,
 		Command command,
 		String modelName,
 		String connectorBindingId, int nodeID)
 		throws TeiidComponentException, TeiidProcessingException {          
 
         if(tempTableStore != null) {
-            TupleSource result = tempTableStore.registerRequest(command);
+            TupleSource result = tempTableStore.registerRequest(context, command);
             if (result != null) {
             	return result;
             }
         }
-        return this.processorDataManager.registerRequest(processorID, command, modelName, connectorBindingId, nodeID);
+        return this.processorDataManager.registerRequest(context, command, modelName, connectorBindingId, nodeID);
 	}
 
     public Object lookupCodeValue(

Modified: trunk/engine/src/main/java/org/teiid/query/processor/proc/AssignmentInstruction.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/proc/AssignmentInstruction.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/main/java/org/teiid/query/processor/proc/AssignmentInstruction.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -33,7 +33,6 @@
 import org.teiid.logging.LogConstants;
 import org.teiid.logging.LogManager;
 import org.teiid.query.analysis.AnalysisRecord;
-import org.teiid.query.processor.program.ProgramInstruction;
 import org.teiid.query.sql.symbol.ElementSymbol;
 import org.teiid.query.sql.symbol.Expression;
 import org.teiid.query.sql.util.VariableContext;
@@ -120,7 +119,7 @@
     }
     
     /** 
-     * @see org.teiid.query.processor.program.ProgramInstruction#clone()
+     * @see org.teiid.query.processor.proc.ProgramInstruction#clone()
      */
     public AssignmentInstruction clone() {
         AssignmentInstruction clone = new AssignmentInstruction();

Modified: trunk/engine/src/main/java/org/teiid/query/processor/proc/BreakInstruction.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/proc/BreakInstruction.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/main/java/org/teiid/query/processor/proc/BreakInstruction.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -26,7 +26,6 @@
 
 import org.teiid.client.plan.PlanNode;
 import org.teiid.core.TeiidComponentException;
-import org.teiid.query.processor.program.ProgramInstruction;
 
 
 /**

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	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/main/java/org/teiid/query/processor/proc/CreateCursorResultSetInstruction.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -31,7 +31,6 @@
 import org.teiid.core.TeiidComponentException;
 import org.teiid.core.TeiidProcessingException;
 import org.teiid.query.processor.ProcessorPlan;
-import org.teiid.query.processor.program.ProgramInstruction;
 
 
 /**

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	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/main/java/org/teiid/query/processor/proc/ErrorInstruction.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -29,7 +29,6 @@
 import org.teiid.core.TeiidComponentException;
 import org.teiid.core.TeiidProcessingException;
 import org.teiid.logging.LogManager;
-import org.teiid.query.processor.program.ProgramInstruction;
 import org.teiid.query.sql.symbol.Expression;
 
 
@@ -54,7 +53,7 @@
 	}
     
     /** 
-     * @see org.teiid.query.processor.program.ProgramInstruction#clone()
+     * @see org.teiid.query.processor.proc.ProgramInstruction#clone()
      */
     public ErrorInstruction clone() {
         ErrorInstruction clone = new ErrorInstruction();

Modified: trunk/engine/src/main/java/org/teiid/query/processor/proc/ExecDynamicSqlInstruction.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/proc/ExecDynamicSqlInstruction.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/main/java/org/teiid/query/processor/proc/ExecDynamicSqlInstruction.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -49,8 +49,6 @@
 import org.teiid.query.optimizer.capabilities.CapabilitiesFinder;
 import org.teiid.query.parser.QueryParser;
 import org.teiid.query.processor.ProcessorPlan;
-import org.teiid.query.processor.program.Program;
-import org.teiid.query.processor.program.ProgramInstruction;
 import org.teiid.query.resolver.QueryResolver;
 import org.teiid.query.resolver.util.ResolveVirtualGroupCriteriaVisitor;
 import org.teiid.query.rewriter.QueryRewriter;

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	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/main/java/org/teiid/query/processor/proc/IfInstruction.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -29,8 +29,6 @@
 import org.teiid.core.TeiidComponentException;
 import org.teiid.core.TeiidProcessingException;
 import org.teiid.logging.LogManager;
-import org.teiid.query.processor.program.Program;
-import org.teiid.query.processor.program.ProgramInstruction;
 import org.teiid.query.sql.lang.Criteria;
 
 

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	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/main/java/org/teiid/query/processor/proc/LoopInstruction.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -33,7 +33,6 @@
 import org.teiid.core.TeiidComponentException;
 import org.teiid.core.TeiidProcessingException;
 import org.teiid.query.processor.ProcessorPlan;
-import org.teiid.query.processor.program.Program;
 import org.teiid.query.sql.symbol.ElementSymbol;
 import org.teiid.query.sql.symbol.SingleElementSymbol;
 import org.teiid.query.sql.util.VariableContext;

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	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/main/java/org/teiid/query/processor/proc/ProcedurePlan.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -55,8 +55,6 @@
 import org.teiid.query.processor.ProcessorPlan;
 import org.teiid.query.processor.QueryProcessor;
 import org.teiid.query.processor.TempTableDataManager;
-import org.teiid.query.processor.program.Program;
-import org.teiid.query.processor.program.ProgramInstruction;
 import org.teiid.query.processor.relational.SubqueryAwareEvaluator;
 import org.teiid.query.sql.ProcedureReservedWords;
 import org.teiid.query.sql.lang.Criteria;
@@ -204,7 +202,7 @@
 		            context.setValue(entry.getKey(), value);
 				}
     		}
-    		tempTableStore = new TempTableStore(bufferMgr, getContext().getConnectionID(), null);
+    		tempTableStore = new TempTableStore(bufferMgr, getContext().getConnectionID());
             this.dataMgr = new TempTableDataManager(dataMgr, tempTableStore);
     	}
     	this.evaluatedParams = true;
@@ -422,7 +420,7 @@
 		        //this may not be the first time the plan is being run
 		        command.reset();
 		
-		        CommandContext subContext = (CommandContext) getContext().clone();
+		        CommandContext subContext = getContext().clone();
 		        subContext.setVariableContext(this.currentVarContext);
 		        subContext.setTempTableStore(getTempTableStore());
 		        state = new CursorState();

Copied: trunk/engine/src/main/java/org/teiid/query/processor/proc/Program.java (from rev 2390, trunk/engine/src/main/java/org/teiid/query/processor/program/Program.java)
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/proc/Program.java	                        (rev 0)
+++ trunk/engine/src/main/java/org/teiid/query/processor/proc/Program.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -0,0 +1,216 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.query.processor.proc;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.teiid.client.plan.PlanNode;
+
+
+/**
+ * A program is a sequence of {@link ProgramInstruction ProgramInstruction}.  Certain
+ * ProgramInstructions, such as {@link IfInstruction} and {@link WhileInstruction} may 
+ * have pointers to sub programs.
+ */
+public class Program implements Cloneable {
+
+    private List<ProgramInstruction> programInstructions;
+    private int counter = 0;
+
+	/**
+	 * Constructor for Program.
+	 */
+	public Program() {
+		super();
+	}
+
+    /**
+     * Returns the next instruction to be executed, or null if there are
+     * none or no more instructions.
+     * @return ProgramInstruction to be executed next, or null if there
+     * are no more to execute (or if this Program is empty)
+     */
+    public ProgramInstruction getCurrentInstruction(){
+        return getInstructionAtIndex(counter);
+    }
+
+    /**
+     * Increments the program counter, so that the next call to
+     * {@link #getCurrentInstruction} will return the following
+     * instruction.  This method is intended to be used by a 
+     * ProcessingInstruction itself, to control the flow of execution.
+     */
+    public void incrementProgramCounter(){
+        counter++;
+    }
+    
+    /**
+     * Decrements the program counter, so that the next call to
+     * {@link #getCurrentInstruction} will return the previous
+     * instruction.  This method is intended to be used by a 
+     * ProcessingInstruction itself, to control the flow of execution.
+     */
+    public void decrementProgramCounter(){
+        counter--;
+    }
+    
+    /**
+     * Resets this program, so it can be run through again.
+     */
+    public void resetProgramCounter(){
+        counter = 0;
+    }
+
+    int getProgramCounter(){
+        return counter;
+    }
+
+
+    /**
+     * Returns the instruction to be executed at the indicated index,
+     * or null if there is no instruction at that index.
+     * @return instruction to be executed at the indicated index,
+     * or null if there is no instruction at that index.
+     */
+    public ProgramInstruction getInstructionAt(int instructionIndex){
+        return getInstructionAtIndex(instructionIndex);
+    }
+
+    
+    public void addInstruction(ProgramInstruction instruction){
+        if (instruction != null){
+            getProcessorInstructions().add(instruction);
+        }
+    }
+
+    public void addInstructions(Program instructions){
+        if (instructions != null){
+            getProcessorInstructions().addAll(instructions.getProcessorInstructions());
+        }
+    }
+
+    /**
+     * Produces a deep clone.
+     */
+    public Object clone(){
+        Program program = new Program();
+        program.counter = this.counter;
+        
+        if (this.programInstructions != null){
+            ArrayList<ProgramInstruction> clonedInstructions = new ArrayList<ProgramInstruction>(this.programInstructions.size());
+            for (ProgramInstruction pi : this.programInstructions) {
+                clonedInstructions.add( pi.clone() );
+            }
+            program.programInstructions = clonedInstructions;
+        }
+        
+        return program;
+    }
+
+    public PlanNode getDescriptionProperties() {
+    	PlanNode props = new PlanNode("Program"); //$NON-NLS-1$
+        
+        if(this.programInstructions != null) {
+        	for (int i = 0; i < programInstructions.size(); i++) {
+                ProgramInstruction inst = programInstructions.get(i);
+                PlanNode childProps = inst.getDescriptionProperties();
+                props.addProperty("Instruction " + i, childProps); //$NON-NLS-1$
+            }
+        }
+        return props;
+    }
+    
+    //=========================================================================
+    //UTILITY
+    //=========================================================================
+
+    /**
+     * Returns the instruction to be executed at the indicated index,
+     * or null if there is no instruction at that index.
+     * @return instruction to be executed at the indicated index,
+     * or null if there is no instruction at that index.
+     */
+    private ProgramInstruction getInstructionAtIndex(int instructionIndex){
+        if (programInstructions != null){
+            if (instructionIndex < getProcessorInstructions().size()){ 
+                return getProcessorInstructions().get(instructionIndex);
+            }
+        }
+        return null;
+    }
+
+    public List<ProgramInstruction> getProcessorInstructions(){
+        if (programInstructions == null){
+            programInstructions = new ArrayList<ProgramInstruction>();
+        }
+        return programInstructions;
+    }
+    
+    public String toString() {
+        StringBuilder str = new StringBuilder();   
+            
+        programToString(str);
+        
+        return "PROGRAM counter " + this.counter + "\n" + str.toString(); //$NON-NLS-1$ //$NON-NLS-2$ 
+    }
+
+    /**
+     * This method calls itself recursively if either a While or If instruction is encountered. 
+     * The sub program(s) from those kinds of instructions are passed, recursively, into this
+     * method.
+     */
+    private final void programToString(StringBuilder str) {
+
+        int instructionIndex = 0;
+        ProgramInstruction inst = getInstructionAt(instructionIndex);
+    
+        while(inst != null) {
+            
+            printLine(instructionIndex++, inst.toString(), str);
+
+			if(instructionIndex > 1000) { 
+			    printLine(instructionIndex, "[OUTPUT TRUNCATED...]", str); //$NON-NLS-1$
+			    break;
+			}
+
+            inst = getInstructionAt(instructionIndex);
+        }
+    }
+
+    private static final void printLine(int counter, String line, StringBuilder buffer) {
+        // Pad counter with spaces
+        String counterStr = "" + counter + ": "; //$NON-NLS-1$ //$NON-NLS-2$
+        if(counter < 10) { 
+            counterStr += " ";     //$NON-NLS-1$
+        }
+        if(counterStr.length() == 1) { 
+            counterStr += "  "; //$NON-NLS-1$
+        } else if(counterStr.length() == 2) { 
+            counterStr += " ";     //$NON-NLS-1$
+        } 
+        
+        buffer.append(counterStr + line + "\n"); //$NON-NLS-1$
+    }
+        
+}

Copied: trunk/engine/src/main/java/org/teiid/query/processor/proc/ProgramInstruction.java (from rev 2390, trunk/engine/src/main/java/org/teiid/query/processor/program/ProgramInstruction.java)
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/proc/ProgramInstruction.java	                        (rev 0)
+++ trunk/engine/src/main/java/org/teiid/query/processor/proc/ProgramInstruction.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -0,0 +1,85 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.query.processor.proc;
+
+import java.util.List;
+
+import org.teiid.client.plan.PlanNode;
+import org.teiid.core.TeiidComponentException;
+import org.teiid.core.TeiidProcessingException;
+import org.teiid.query.processor.ProcessorPlan;
+
+
+/**
+ * <p>Abstract superclass of all program instructions.</p>
+ * 
+ * <p>All processor
+ * instructions need to be cloneable, but it most cases the default 
+ * Object.clone operation will suffice, since in most cases the processing
+ * instructions will be stateless, or the state will be immutable.
+ * The exception to this are instructions that have sub programs in them -
+ * those sub programs need to be cloned.</p>
+ */
+public abstract class ProgramInstruction implements Cloneable {
+
+    public ProgramInstruction() {
+    } 
+   
+    /**
+     * Allow this instruction to do whatever processing it needs, and to
+     * in turn manipulate the running program. A typical instruction should simply {@link
+     * Program#incrementProgramCounter increment} the program counter of the current program, but specialized
+     * instructions may add sub programs to the stack or not increment the counter (so that they are executed again.)
+     */
+    public abstract void process(ProcedurePlan env) 
+        throws TeiidComponentException, TeiidProcessingException;
+        
+    /**
+     * Finds all nested plans and returns them.
+     * @return List of ProcessorPlan 
+     * @since 4.2
+     */
+    public List<ProcessorPlan> getChildPlans() {
+        return null;
+    }
+    
+    /**
+     * Override Object.clone() to make the method public.  This method 
+     * simply calls super.clone(), deferring to the default shallow
+     * cloning.  Some ProcessorInstruction subclasses may need to 
+     * override with custom safe or deep cloning.
+     * @return shallow clone
+     */
+    public ProgramInstruction clone() {
+        try {
+            return (ProgramInstruction)super.clone();
+        } catch (CloneNotSupportedException e) {
+            //should never get here, since
+            //this Class does support clone
+        }
+        return null;
+    }
+
+	public abstract PlanNode getDescriptionProperties();
+    
+}

Modified: trunk/engine/src/main/java/org/teiid/query/processor/proc/RepeatedInstruction.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/proc/RepeatedInstruction.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/main/java/org/teiid/query/processor/proc/RepeatedInstruction.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -24,7 +24,6 @@
 
 import org.teiid.core.TeiidComponentException;
 import org.teiid.core.TeiidProcessingException;
-import org.teiid.query.processor.program.Program;
 
 
 public interface RepeatedInstruction {

Modified: trunk/engine/src/main/java/org/teiid/query/processor/proc/WhileInstruction.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/proc/WhileInstruction.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/main/java/org/teiid/query/processor/proc/WhileInstruction.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -29,8 +29,6 @@
 import org.teiid.client.plan.PlanNode;
 import org.teiid.core.TeiidComponentException;
 import org.teiid.core.TeiidProcessingException;
-import org.teiid.query.processor.program.Program;
-import org.teiid.query.processor.program.ProgramInstruction;
 import org.teiid.query.sql.lang.Criteria;
 
 

Modified: trunk/engine/src/main/java/org/teiid/query/processor/relational/AccessNode.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/relational/AccessNode.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/main/java/org/teiid/query/processor/relational/AccessNode.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -173,7 +173,7 @@
 
 	private void registerRequest(Command atomicCommand)
 			throws TeiidComponentException, TeiidProcessingException {
-		tupleSource = getDataManager().registerRequest(this.getContext().getProcessorID(), atomicCommand, modelName, connectorBindingId, getID());
+		tupleSource = getDataManager().registerRequest(getContext(), atomicCommand, modelName, connectorBindingId, getID());
 	}
 	
 	protected boolean processCommandsIndividually() {

Modified: trunk/engine/src/main/java/org/teiid/query/processor/relational/BatchedUpdateNode.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/relational/BatchedUpdateNode.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/main/java/org/teiid/query/processor/relational/BatchedUpdateNode.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -92,7 +92,7 @@
             Command updateCommand = (Command)updateCommands.get(i).clone();
             CommandContext context = this.getContext();
             if (this.contexts != null && !this.contexts.isEmpty()) {
-            	context = (CommandContext)context.clone();
+            	context = context.clone();
             	context.setVariableContext(this.contexts.get(i));
             }
             boolean needProcessing = false;
@@ -110,7 +110,7 @@
         }
         if (!commandsToExecute.isEmpty()) {
             BatchedUpdateCommand command = new BatchedUpdateCommand(commandsToExecute);
-            tupleSource = getDataManager().registerRequest(this.getContext().getProcessorID(), command, modelName, null, getID());
+            tupleSource = getDataManager().registerRequest(getContext(), command, modelName, null, getID());
         }
     }
     

Modified: trunk/engine/src/main/java/org/teiid/query/processor/relational/DependentProcedureAccessNode.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/relational/DependentProcedureAccessNode.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/main/java/org/teiid/query/processor/relational/DependentProcedureAccessNode.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -79,7 +79,7 @@
     @Override
     public void open() throws TeiidComponentException,
     		TeiidProcessingException {
-    	CommandContext context  = (CommandContext)getContext().clone();
+    	CommandContext context  = getContext().clone();
     	context.pushVariableContext(new VariableContext());
     	this.setContext(context);
     	DependentProcedureExecutionNode.shareVariableContext(this, context);

Modified: trunk/engine/src/main/java/org/teiid/query/processor/relational/PlanExecutionNode.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/relational/PlanExecutionNode.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/main/java/org/teiid/query/processor/relational/PlanExecutionNode.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -69,7 +69,7 @@
 		throws TeiidComponentException, TeiidProcessingException {
 		super.open();
         // Initialize plan for execution
-        CommandContext subContext = (CommandContext) getContext().clone();
+        CommandContext subContext = getContext().clone();
         subContext.pushVariableContext(new VariableContext());
         plan.initialize(subContext, getDataManager(), this.getBufferManager());        
         

Modified: trunk/engine/src/main/java/org/teiid/query/processor/relational/ProjectIntoNode.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/relational/ProjectIntoNode.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/main/java/org/teiid/query/processor/relational/ProjectIntoNode.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -224,7 +224,7 @@
     }
 
     private void registerRequest(Command command) throws TeiidComponentException, TeiidProcessingException {
-    	tupleSource = getDataManager().registerRequest(this.getContext().getProcessorID(), command, this.modelName, null, getID());        
+    	tupleSource = getDataManager().registerRequest(getContext(), command, this.modelName, null, getID());        
     }
     
     private void closeRequest() {

Modified: trunk/engine/src/main/java/org/teiid/query/processor/relational/SubqueryAwareEvaluator.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/relational/SubqueryAwareEvaluator.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/main/java/org/teiid/query/processor/relational/SubqueryAwareEvaluator.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -112,7 +112,7 @@
 		}
 		if (!state.done) {
 			if (state.processor == null) {
-				CommandContext subContext = (CommandContext) context.clone();
+				CommandContext subContext = context.clone();
 				state.plan.reset();
 		        state.processor = new QueryProcessor(state.plan, subContext, manager, this.dataMgr);
 		        if (container.getCommand().getCorrelatedReferences() != null) { 

Modified: trunk/engine/src/main/java/org/teiid/query/processor/xml/InitializeDocumentInstruction.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/xml/InitializeDocumentInstruction.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/main/java/org/teiid/query/processor/xml/InitializeDocumentInstruction.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -30,7 +30,6 @@
 import org.teiid.core.TeiidProcessingException;
 import org.teiid.logging.LogManager;
 import org.teiid.query.mapping.xml.MappingNodeConstants;
-import org.teiid.query.util.XMLFormatConstants;
 
 
 /**
@@ -93,9 +92,9 @@
             boolean formatted = this.isFormatted;
             String xmlFormat = env.getXMLFormat();
             if(xmlFormat != null) {
-                if(xmlFormat.equalsIgnoreCase(XMLFormatConstants.XML_TREE_FORMAT)) {
+                if(xmlFormat.equalsIgnoreCase(XMLPlan.XML_TREE_FORMAT)) {
                     formatted = true;
-                } else if (xmlFormat.equalsIgnoreCase(XMLFormatConstants.XML_COMPACT_FORMAT)) {
+                } else if (xmlFormat.equalsIgnoreCase(XMLPlan.XML_COMPACT_FORMAT)) {
                     formatted = false;
                 }
             }

Modified: trunk/engine/src/main/java/org/teiid/query/processor/xml/RelationalPlanExecutor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/xml/RelationalPlanExecutor.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/main/java/org/teiid/query/processor/xml/RelationalPlanExecutor.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -72,7 +72,7 @@
         this.bufferMgr = bufferMgr;
         
         ProcessorPlan plan = resultInfo.getPlan();
-        CommandContext subContext = (CommandContext)context.clone();
+        CommandContext subContext = context.clone();
         subContext.pushVariableContext(new VariableContext());
         this.internalProcessor = new QueryProcessor(plan, subContext, bufferMgr, dataMgr);
     }

Modified: trunk/engine/src/main/java/org/teiid/query/processor/xml/XMLPlan.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/xml/XMLPlan.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/main/java/org/teiid/query/processor/xml/XMLPlan.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -47,8 +47,8 @@
 import org.teiid.common.buffer.BufferManager;
 import org.teiid.common.buffer.TupleBatch;
 import org.teiid.core.TeiidComponentException;
+import org.teiid.core.TeiidException;
 import org.teiid.core.TeiidProcessingException;
-import org.teiid.core.TeiidException;
 import org.teiid.core.types.DataTypeManager;
 import org.teiid.core.types.XMLType;
 import org.teiid.logging.LogConstants;
@@ -61,7 +61,6 @@
 import org.teiid.query.sql.symbol.ElementSymbol;
 import org.teiid.query.sql.symbol.GroupSymbol;
 import org.teiid.query.tempdata.TempTableStore;
-import org.teiid.query.tempdata.TempTableStore;
 import org.teiid.query.util.CommandContext;
 import org.teiid.query.util.ErrorMessageKeys;
 import org.xml.sax.Attributes;
@@ -94,6 +93,10 @@
         
     // Post-processing
 	private Collection<SQLXML> xmlSchemas;
+	/**  XML results format:  XML results displayed as a tree*/
+	public static final String XML_TREE_FORMAT = "Tree"; //$NON-NLS-1$
+	/**  XML results format:  XML results displayed in compact form*/
+	public static final String XML_COMPACT_FORMAT = "Compact"; //$NON-NLS-1$
 
     /**
      * Constructor for XMLPlan.
@@ -108,8 +111,8 @@
      */
     public void initialize(CommandContext context, ProcessorDataManager dataMgr, BufferManager bufferMgr) {
         setContext(context);
-        TempTableStore tempTableStore = new TempTableStore(bufferMgr, context.getConnectionID(), (TempTableStore)context.getTempTableStore());
-        //this.dataMgr = new StagingTableDataManager(new TempTableDataManager(dataMgr, tempTableStore), env);
+        TempTableStore tempTableStore = new TempTableStore(bufferMgr, context.getConnectionID());
+        tempTableStore.setParentTempTableStore(context.getTempTableStore());
         this.dataMgr = new TempTableDataManager(dataMgr, tempTableStore);
         this.bufferMgr = bufferMgr;
         this.env.initialize(context, this.dataMgr, this.bufferMgr);

Modified: trunk/engine/src/main/java/org/teiid/query/sql/lang/From.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/lang/From.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/main/java/org/teiid/query/sql/lang/From.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -107,11 +107,10 @@
      * Adds a new collection of groups to the list
      * @param groups Collection of {@link GroupSymbol}
      */
-    public void addGroups( Collection groups ) {
+    public void addGroups( Collection<GroupSymbol> groups ) {
     	if(groups != null) {
-			Iterator iter = groups.iterator();
-			while(iter.hasNext()) {
-				clauses.add(new UnaryFromClause((GroupSymbol) iter.next()));
+    		for (GroupSymbol groupSymbol : groups) {
+				clauses.add(new UnaryFromClause(groupSymbol));
 			}
         }
     }
@@ -120,8 +119,8 @@
      * Returns an ordered list of the groups in all sub-clauses.
      * @return List of {@link GroupSymbol}
      */
-    public List getGroups() {
-        List groups = new ArrayList();
+    public List<GroupSymbol> getGroups() {
+        List<GroupSymbol> groups = new ArrayList<GroupSymbol>();
         if(clauses != null) {
             for(int i=0; i<clauses.size(); i++) {
                 FromClause clause = (FromClause) clauses.get(i);

Modified: trunk/engine/src/main/java/org/teiid/query/sql/symbol/GroupSymbol.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/symbol/GroupSymbol.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/main/java/org/teiid/query/sql/symbol/GroupSymbol.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -38,8 +38,8 @@
  * first would have name=G, definition=Group1 and the second would have
  * name=Group2, definition=null.</p>
  */
-public class GroupSymbol extends Symbol implements Comparable {
-    
+public class GroupSymbol extends Symbol implements Comparable<GroupSymbol> {
+	
     public static final String TEMP_GROUP_PREFIX = "#"; //$NON-NLS-1$
 
 	/** Definition of the symbol, may be null */
@@ -49,7 +49,7 @@
 	private Object metadataID;
     
     private boolean isTempTable;
-    
+    private boolean isGlobalTable;
     private boolean isProcedure;
     
     private String outputDefinition;
@@ -152,6 +152,8 @@
     
     /**
      * Returns true if this is a symbol for a temporary (implicit or explicit) group
+     * May return false for explicit temp tables prior to resolving.
+     * see {@link #isTempTable()}
      * @return
      * @since 5.5
      */
@@ -160,24 +162,16 @@
     }
     
     public boolean isImplicitTempGroupSymbol() {
-        return isTempGroupName(getName()) || isTempGroupName(getDefinition());
+        return isTempGroupName(getNonCorrelationName());
     }
 
 	/**
-	 * Compare two groups and give an ordering.  This is done with the hashcode of the
-	 * lowercased group name.  The order is stable.
+	 * Compare two groups and give an ordering.
 	 * @param other Other group
 	 * @return -1, 0, or 1 depending on how this compares to group
 	 */
-	public int compareTo(Object other) {
-		int diff = other.hashCode() - this.hashCode();
-		if(diff == 0) {
-			return 0;
-		} else if(diff <0) {
-			return -1;
-		} else {
-			return 1;
-		}
+    public int compareTo(GroupSymbol o) {
+    	return getCanonicalName().compareTo(o.getCanonicalName());
 	}
 
 	/**
@@ -193,6 +187,7 @@
         copy.setProcedure(isProcedure);
         copy.setOutputDefinition(this.getOutputDefinition());
         copy.setOutputName(this.getOutputName());
+        copy.isGlobalTable = isGlobalTable;
 		return copy;
 	}
 
@@ -206,7 +201,7 @@
 			return true;
 		}
 
-		if(obj == null || ! (obj instanceof GroupSymbol)) {
+		if(!(obj instanceof GroupSymbol)) {
 			return false;
 		}
 		GroupSymbol other = (GroupSymbol) obj;
@@ -237,6 +232,11 @@
         return name.startsWith(TEMP_GROUP_PREFIX);
     }
 
+    /**
+     * Returns if this is a Temp Table 
+     * Set after resolving.
+     * @return
+     */
     public boolean isTempTable() {
         return this.isTempTable;
     }
@@ -256,4 +256,12 @@
     public void setOutputDefinition(String outputDefinition) {
         this.outputDefinition = outputDefinition;
     }
+    
+    public boolean isGlobalTable() {
+		return isGlobalTable;
+	}
+    
+    public void setGlobalTable(boolean isGlobalTable) {
+		this.isGlobalTable = isGlobalTable;
+	}
 }

Modified: trunk/engine/src/main/java/org/teiid/query/tempdata/TempTable.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/tempdata/TempTable.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/main/java/org/teiid/query/tempdata/TempTable.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -29,6 +29,7 @@
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
 
 import org.teiid.api.exception.query.ExpressionEvaluationException;
 import org.teiid.common.buffer.BlockedException;
@@ -43,6 +44,8 @@
 import org.teiid.core.TeiidException;
 import org.teiid.core.TeiidProcessingException;
 import org.teiid.core.types.DataTypeManager;
+import org.teiid.logging.LogConstants;
+import org.teiid.logging.LogManager;
 import org.teiid.query.QueryPlugin;
 import org.teiid.query.eval.Evaluator;
 import org.teiid.query.metadata.TempMetadataID;
@@ -124,7 +127,8 @@
 			this.eval = new Evaluator(map, null, null);
 			this.condition = condition;
 			this.project = shouldProject();
-			reserved = reserveBuffers();
+			this.reserved = reserveBuffers();
+			lock.readLock().lock();
 		}
 
 		@Override
@@ -152,6 +156,7 @@
 		
 		@Override
 		public void closeSource() {
+			lock.readLock().unlock();
 			bm.releaseBuffers(reserved);
 			reserved = 0;
 			browser.closeSource();
@@ -191,6 +196,8 @@
 		
 		int process() throws ExpressionEvaluationException, TeiidComponentException, TeiidProcessingException {
 			int reserved = reserveBuffers();
+			boolean held = lock.writeLock().isHeldByCurrentThread();
+			lock.writeLock().lock();
 			boolean success = false;
 			try {
 				while (currentTuple != null || (currentTuple = ts.nextTuple()) != null) {
@@ -207,18 +214,22 @@
 				success = true;
 			} finally {
 				bm.releaseBuffers(reserved);
-				if (!success) {
-					TupleSource undoTs = undoLog.createIndexedTupleSource();
-					List<?> tuple = null;
-					try {
+				try {
+					if (!success) {
+						TupleSource undoTs = undoLog.createIndexedTupleSource();
+						List<?> tuple = null;
 						while ((tuple = undoTs.nextTuple()) != null) {
 							undo(tuple);
 						}
-					} catch (TeiidException e) {
-						
 					}
+				} catch (TeiidException e) {
+					LogManager.logError(LogConstants.CTX_DQP, e, e.getMessage());
+				} finally {
+					if (!held) {
+						lock.writeLock().unlock();
+					}
+					close();
 				}
-				close();
 			}
 			return updateCount;
 		}
@@ -243,6 +254,7 @@
 	private BufferManager bm;
 	private String sessionID;
 	private TempMetadataID tid;
+	private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
 	
 	private int keyBatchSize;
 	private int leafBatchSize;
@@ -255,9 +267,9 @@
     		id.setType(DataTypeManager.DefaultDataClasses.INTEGER);
     		columns.add(0, id);
     		rowId = new AtomicInteger();
-        	tree = bm.createSTree(columns, sessionID, TupleSourceType.PROCESSOR, 1);
+        	tree = bm.createSTree(columns, sessionID, 1);
         } else {
-        	tree = bm.createSTree(columns, sessionID, TupleSourceType.PROCESSOR, primaryKeyLength);
+        	tree = bm.createSTree(columns, sessionID, primaryKeyLength);
         }
 		this.columns = columns;
 		this.sessionID = sessionID;

Modified: trunk/engine/src/main/java/org/teiid/query/tempdata/TempTableStore.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/tempdata/TempTableStore.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/main/java/org/teiid/query/tempdata/TempTableStore.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -24,11 +24,11 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
 
 import org.teiid.api.exception.query.QueryProcessingException;
 import org.teiid.common.buffer.BufferManager;
@@ -55,6 +55,7 @@
 import org.teiid.query.sql.symbol.Expression;
 import org.teiid.query.sql.symbol.GroupSymbol;
 import org.teiid.query.sql.visitor.ExpressionMappingVisitor;
+import org.teiid.query.util.CommandContext;
 
 /** 
  * @since 5.5
@@ -62,25 +63,21 @@
 public class TempTableStore {
 
 	private BufferManager buffer;
-    private TempMetadataStore tempMetadataStore = new TempMetadataStore();
-    private Map<String, TempTable> groupToTupleSourceID = new HashMap<String, TempTable>();
+    private TempMetadataStore tempMetadataStore = new TempMetadataStore(new ConcurrentHashMap<String, TempMetadataID>());
+    private Map<String, TempTable> groupToTupleSourceID = new ConcurrentHashMap<String, TempTable>();
     private String sessionID;
     private TempTableStore parentTempTableStore;
     
-    public TempTableStore(BufferManager buffer, String sessionID, TempTableStore parentTempTableStore) {
+    public TempTableStore(BufferManager buffer, String sessionID) {
         this.buffer = buffer;
         this.sessionID = sessionID;
-        this.parentTempTableStore = parentTempTableStore;
     }
+    
+    public void setParentTempTableStore(TempTableStore parentTempTableStore) {
+		this.parentTempTableStore = parentTempTableStore;
+	}
 
-    void addTempTable(Create create, boolean removeExistingTable) throws QueryProcessingException{
-    	String tempTableName = create.getTable().getName().toUpperCase();
-        if(tempMetadataStore.getTempGroupID(tempTableName) != null) {
-            if(!removeExistingTable) {
-                throw new QueryProcessingException(QueryExecPlugin.Util.getString("TempTableStore.table_exist_error", tempTableName));//$NON-NLS-1$
-            }
-            removeTempTableByName(tempTableName);
-        }
+    void addTempTable(String tempTableName, Create create) {
     	List<ElementSymbol> columns = create.getColumns();
     	
         //add metadata
@@ -109,15 +106,15 @@
         return tempMetadataStore;
     }
         
-    public TupleSource registerRequest(Command command) throws TeiidComponentException, TeiidProcessingException{
+    public TupleSource registerRequest(CommandContext context, Command command) throws TeiidComponentException, TeiidProcessingException{
         if (command instanceof Query) {
             Query query = (Query)command;
-            GroupSymbol group = (GroupSymbol)query.getFrom().getGroups().get(0);
+            GroupSymbol group = query.getFrom().getGroups().get(0);
             if (!group.isTempGroupSymbol()) {
             	return null;
             }
             final String tableName = group.getNonCorrelationName().toUpperCase();
-            TempTable table = getTempTable(tableName, command);
+            TempTable table = getOrCreateTempTable(tableName, command, true);
             //convert to the actual table symbols (this is typically handled by the languagebridgefactory
             ExpressionMappingVisitor emv = new ExpressionMappingVisitor(null) {
             	@Override
@@ -138,7 +135,7 @@
         		return null;
         	}
         	final String groupKey = group.getNonCorrelationName().toUpperCase();
-            final TempTable table = getTempTable(groupKey, command);
+            final TempTable table = getOrCreateTempTable(groupKey, command, false);
         	if (command instanceof Insert) {
         		Insert insert = (Insert)command;
         		TupleSource ts = insert.getTupleSource();
@@ -169,11 +166,15 @@
         }
     	if (command instanceof Create) {
     		Create create = (Create)command;
-    		addTempTable(create, false);
+    		String tempTableName = create.getTable().getCanonicalName();
+    		if(tempMetadataStore.getTempGroupID(tempTableName) != null) {
+                throw new QueryProcessingException(QueryExecPlugin.Util.getString("TempTableStore.table_exist_error", tempTableName));//$NON-NLS-1$
+            }
+    		addTempTable(tempTableName, create);
             return CollectionTupleSource.createUpdateCountTupleSource(0);	
     	}
     	if (command instanceof Drop) {
-    		String tempTableName = ((Drop)command).getTable().getName().toUpperCase();
+    		String tempTableName = ((Drop)command).getTable().getCanonicalName();
             removeTempTableByName(tempTableName);
             return CollectionTupleSource.createUpdateCountTupleSource(0);
     	}
@@ -181,17 +182,17 @@
     }
     
     public void removeTempTables() {
-        for (String name : new ArrayList<String>( groupToTupleSourceID.keySet() )) {
+        for (String name : groupToTupleSourceID.keySet()) {
             removeTempTableByName(name);
         }
     }
     
-    private TempTable getTempTable(String tempTableID, Command command) throws QueryProcessingException{
+    private TempTable getOrCreateTempTable(String tempTableID, Command command, boolean delegate) throws QueryProcessingException{
     	TempTable tsID = groupToTupleSourceID.get(tempTableID);
         if(tsID != null) {
             return tsID;
         }
-        if(this.parentTempTableStore != null){
+        if(delegate && this.parentTempTableStore != null){
     		tsID = this.parentTempTableStore.groupToTupleSourceID.get(tempTableID);
     	    if(tsID != null) {
     	        return tsID;
@@ -212,34 +213,9 @@
         Create create = new Create();
         create.setTable(new GroupSymbol(tempTableID));
         create.setColumns(columns);
-        addTempTable(create, true);       
+        addTempTable(tempTableID, create);       
         return groupToTupleSourceID.get(tempTableID);
     }
-
-    public boolean hasTempTable(Command command){
-        switch (command.getType()) {
-            case Command.TYPE_INSERT:
-            {
-                Insert insert = (Insert)command;
-                GroupSymbol group = insert.getGroup();
-                return group.isTempGroupSymbol();
-            }
-            case Command.TYPE_QUERY:
-            {
-                if(command instanceof Query) {
-                    Query query = (Query)command;
-                    GroupSymbol group = (GroupSymbol)query.getFrom().getGroups().get(0);
-                    return group.isTempGroupSymbol(); 
-                }
-                break;
-            }
-            case Command.TYPE_CREATE:
-                return true;
-            case Command.TYPE_DROP:
-                return true;
-        }
-        return false;
-    }
     
     public Set<String> getAllTempTables() {
         return new HashSet<String>(this.groupToTupleSourceID.keySet());

Modified: trunk/engine/src/main/java/org/teiid/query/util/CommandContext.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/util/CommandContext.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/main/java/org/teiid/query/util/CommandContext.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -42,6 +42,7 @@
 import org.teiid.query.sql.symbol.ElementSymbol;
 import org.teiid.query.sql.symbol.Expression;
 import org.teiid.query.sql.util.VariableContext;
+import org.teiid.query.tempdata.TempTableStore;
 
 /** 
  * Defines the context that a command is processing in.  For example, this defines
@@ -103,12 +104,14 @@
 	    private boolean validateXML;
 	    
 	    private BufferManager bufferManager;
+	    
+	    private TempTableStore globalTables;
 	}
 	
 	private GlobalState globalState = new GlobalState();
 
     private VariableContext variableContext = new VariableContext();
-    private Object tempTableStore;
+    private TempTableStore tempTableStore;
     private LinkedList<String> recursionStack;
 
     /**
@@ -180,10 +183,11 @@
         globalState.processorID = object;
     }
 
-    public Object clone() {
+    public CommandContext clone() {
     	CommandContext clone = new CommandContext();
     	clone.globalState = this.globalState;
     	clone.variableContext = this.variableContext;
+    	clone.tempTableStore = this.tempTableStore;
     	if (this.recursionStack != null) {
             clone.recursionStack = new LinkedList<String>(this.recursionStack);
         }
@@ -355,11 +359,11 @@
         this.globalState.securityFunctionEvaluator = securityFunctionEvaluator;
     }
 
-	public Object getTempTableStore() {
+	public TempTableStore getTempTableStore() {
 		return tempTableStore;
 	}
 
-	public void setTempTableStore(Object tempTableStore) {
+	public void setTempTableStore(TempTableStore tempTableStore) {
 		this.tempTableStore = tempTableStore;
 	}
 	
@@ -454,5 +458,13 @@
     public void setBufferManager(BufferManager bm) {
     	globalState.bufferManager = bm;
     }
+    
+    public TempTableStore getGlobalTableStore() {
+    	return globalState.globalTables;
+    }
+    
+    public void setGlobalTableStore(TempTableStore tempTableStore) {
+    	globalState.globalTables = tempTableStore;
+    }
 	
 }

Deleted: trunk/engine/src/main/java/org/teiid/query/util/XMLFormatConstants.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/util/XMLFormatConstants.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/main/java/org/teiid/query/util/XMLFormatConstants.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -1,37 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * See the COPYRIGHT.txt file distributed with this work for information
- * regarding copyright ownership.  Some portions may be licensed
- * to Red Hat, Inc. under one or more contributor license agreements.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301 USA.
- */
-
-package org.teiid.query.util;
-
-
-/** 
- * @since 5.0
- */
-public interface XMLFormatConstants {
-
-    /**  XML results format:  XML results displayed as a tree*/
-    public static final String XML_TREE_FORMAT = "Tree"; //$NON-NLS-1$
-
-    /**  XML results format:  XML results displayed in compact form*/
-    public static final String XML_COMPACT_FORMAT = "Compact"; //$NON-NLS-1$
-
-}

Modified: trunk/engine/src/test/java/org/teiid/common/buffer/TestSTree.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/common/buffer/TestSTree.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/test/java/org/teiid/common/buffer/TestSTree.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -28,7 +28,6 @@
 import java.util.List;
 
 import org.junit.Test;
-import org.teiid.common.buffer.BufferManager.TupleSourceType;
 import org.teiid.core.TeiidComponentException;
 import org.teiid.query.sql.symbol.ElementSymbol;
 
@@ -42,7 +41,7 @@
 		ElementSymbol e2 = new ElementSymbol("y");
 		e2.setType(String.class);
 		List elements = Arrays.asList(e1, e2);
-		STree map = bm.createSTree(elements, "1", TupleSourceType.PROCESSOR, 1);
+		STree map = bm.createSTree(elements, "1", 1);
 		
 		for (int i = 20000; i > 0; i--) {
 			assertNull(map.insert(Arrays.asList(i, String.valueOf(i)), true));

Modified: trunk/engine/src/test/java/org/teiid/dqp/internal/process/SimpleQueryProcessorFactory.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/dqp/internal/process/SimpleQueryProcessorFactory.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/test/java/org/teiid/dqp/internal/process/SimpleQueryProcessorFactory.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -69,7 +69,7 @@
 				idGenerator, finder, AnalysisRecord.createNonRecordingRecord(),
 				commandContext);
 
-		CommandContext copy = (CommandContext) commandContext.clone();
+		CommandContext copy = commandContext.clone();
 		return new QueryProcessor(plan, copy, bufferMgr, dataMgr);
 	}
 }

Modified: trunk/engine/src/test/java/org/teiid/dqp/internal/process/multisource/TestMultiSourcePlanToProcessConverter.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/dqp/internal/process/multisource/TestMultiSourcePlanToProcessConverter.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/test/java/org/teiid/dqp/internal/process/multisource/TestMultiSourcePlanToProcessConverter.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -73,7 +73,7 @@
             setMustRegisterCommands(false);
         }
 
-        public TupleSource registerRequest(Object processorID, Command command, String modelName, String connectorBindingId, int nodeID) throws org.teiid.core.TeiidComponentException {
+        public TupleSource registerRequest(CommandContext context, Command command, String modelName, String connectorBindingId, int nodeID) throws org.teiid.core.TeiidComponentException {
         	assertNotNull(connectorBindingId);
         	
         	Collection elements = ElementCollectorVisitor.getElements(command, true, true);
@@ -84,7 +84,7 @@
                     fail("Query Contains a MultiSourceElement -- MultiSource expansion did not happen"); //$NON-NLS-1$
                 }
             }
-            return super.registerRequest(processorID, command, modelName, connectorBindingId, nodeID);
+            return super.registerRequest(context, command, modelName, connectorBindingId, nodeID);
         }
     }
 

Copied: trunk/engine/src/test/java/org/teiid/query/optimizer/TestBatchedUpdatePlanner.java (from rev 2390, trunk/engine/src/test/java/org/teiid/query/optimizer/batch/TestBatchedUpdatePlanner.java)
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/optimizer/TestBatchedUpdatePlanner.java	                        (rev 0)
+++ trunk/engine/src/test/java/org/teiid/query/optimizer/TestBatchedUpdatePlanner.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -0,0 +1,230 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.query.optimizer;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.teiid.api.exception.query.QueryMetadataException;
+import org.teiid.api.exception.query.QueryPlannerException;
+import org.teiid.core.TeiidComponentException;
+import org.teiid.core.TeiidProcessingException;
+import org.teiid.query.analysis.AnalysisRecord;
+import org.teiid.query.metadata.QueryMetadataInterface;
+import org.teiid.query.optimizer.QueryOptimizer;
+import org.teiid.query.optimizer.capabilities.CapabilitiesFinder;
+import org.teiid.query.optimizer.capabilities.DefaultCapabilitiesFinder;
+import org.teiid.query.optimizer.capabilities.FakeCapabilitiesFinder;
+import org.teiid.query.optimizer.capabilities.SourceCapabilities;
+import org.teiid.query.parser.QueryParser;
+import org.teiid.query.processor.BatchedUpdatePlan;
+import org.teiid.query.processor.ProcessorPlan;
+import org.teiid.query.processor.relational.AccessNode;
+import org.teiid.query.processor.relational.BatchedUpdateNode;
+import org.teiid.query.processor.relational.ProjectNode;
+import org.teiid.query.processor.relational.RelationalNode;
+import org.teiid.query.processor.relational.RelationalPlan;
+import org.teiid.query.resolver.QueryResolver;
+import org.teiid.query.rewriter.QueryRewriter;
+import org.teiid.query.sql.lang.BatchedUpdateCommand;
+import org.teiid.query.sql.lang.Command;
+import org.teiid.query.unittest.FakeMetadataFactory;
+import org.teiid.query.validator.Validator;
+import org.teiid.query.validator.ValidatorReport;
+
+import junit.framework.TestCase;
+
+
+
+/** 
+ * @since 4.2
+ */
+public class TestBatchedUpdatePlanner extends TestCase {
+
+    public TestBatchedUpdatePlanner(String name) {
+        super(name);
+    }
+    
+    public static List<Command> helpGetCommands(String[] sql, QueryMetadataInterface md) throws TeiidComponentException, TeiidProcessingException  { 
+        if(DEBUG) System.out.println("\n####################################\n" + sql);  //$NON-NLS-1$
+        List<Command> commands = new ArrayList<Command>(sql.length);
+        for (int i = 0; i < sql.length; i++) {
+            Command command = QueryParser.getQueryParser().parseCommand(sql[i]);
+            QueryResolver.resolveCommand(command, md);
+            ValidatorReport repo =  Validator.validate(command, md);
+            Collection failures = new ArrayList();
+            repo.collectInvalidObjects(failures);
+            if (failures.size() > 0){
+                fail("Exception during validation (" + repo); //$NON-NLS-1$
+            }                    
+            
+            command = QueryRewriter.rewrite(command, md, null);
+            commands.add(command);
+        }
+        return commands;
+    }
+    
+    private BatchedUpdateCommand helpGetCommand(String[] sql, QueryMetadataInterface md) throws TeiidComponentException, TeiidProcessingException { 
+        BatchedUpdateCommand command = new BatchedUpdateCommand(helpGetCommands(sql, md));
+        return command;
+    }
+    
+    private BatchedUpdatePlan helpPlanCommand(Command command, QueryMetadataInterface md, CapabilitiesFinder capFinder, boolean shouldSucceed) throws QueryPlannerException, QueryMetadataException, TeiidComponentException { 
+        
+        // plan
+        ProcessorPlan plan = null;
+        AnalysisRecord analysisRecord = new AnalysisRecord(false, DEBUG);
+        if (shouldSucceed) {
+            try {
+                //do planning
+                plan = QueryOptimizer.optimizePlan(command, md, null, capFinder, analysisRecord, null);
+
+            } finally {
+                if(DEBUG) {
+                    System.out.println(analysisRecord.getDebugLog());
+                }
+            }
+            return (BatchedUpdatePlan)plan;
+        }
+        Exception exception = null;
+        try {
+            //do planning
+            QueryOptimizer.optimizePlan(command, md, null, capFinder, analysisRecord, null);
+
+        } catch (QueryPlannerException e) {
+            exception = e;
+        } catch (TeiidComponentException e) {
+            exception = e;
+        } finally {
+            if(DEBUG) {
+                System.out.println(analysisRecord.getDebugLog());
+            }
+        }
+        assertNotNull("Expected exception but did not get one.", exception); //$NON-NLS-1$
+        return null;
+    }
+    
+    public static CapabilitiesFinder getGenericFinder() {
+        return new DefaultCapabilitiesFinder(new FakeCapabilities(true));
+    }
+
+    private BatchedUpdatePlan helpPlan(String[] sql, QueryMetadataInterface md) throws TeiidComponentException, QueryMetadataException, TeiidProcessingException {
+        return helpPlan(sql, md, getGenericFinder(), true);
+    }
+    
+    private BatchedUpdatePlan helpPlan(String[] sql, QueryMetadataInterface md, CapabilitiesFinder capFinder, boolean shouldSucceed) throws TeiidComponentException, QueryMetadataException, TeiidProcessingException {
+        Command command = helpGetCommand(sql, md);
+
+        if (capFinder == null){
+            capFinder = getGenericFinder();
+        }
+
+        return helpPlanCommand(command, md, capFinder, shouldSucceed);
+    } 
+    
+    private void helpAssertIsBatchedPlan(RelationalPlan plan, boolean isBatchedPlan) {
+        RelationalNode node = plan.getRootNode();
+        if (node instanceof ProjectNode) {
+            node = node.getChildren()[0];
+        }
+        if (isBatchedPlan) {
+            assertTrue("Plan should have been a batched", node instanceof BatchedUpdateNode); //$NON-NLS-1$
+        } else {
+            assertTrue("Plan should not have been batched.", node instanceof AccessNode); //$NON-NLS-1$
+        }
+    }
+    
+    private void helpTestPlanner(String[] sql, boolean[] expectedBatching) throws QueryMetadataException, TeiidComponentException, TeiidProcessingException {
+        BatchedUpdatePlan plan = helpPlan(sql, FakeMetadataFactory.example1Cached());
+        List plans = plan.getUpdatePlans();
+        assertEquals("Number of child plans did not match expected", expectedBatching.length, plans.size()); //$NON-NLS-1$
+        for (int i = 0; i < expectedBatching.length; i++) {
+            helpAssertIsBatchedPlan((RelationalPlan)plans.get(i), expectedBatching[i]);
+        }
+    }    
+    
+    private void helpTestPlanner(String[] sql, boolean[] expectedBatching, CapabilitiesFinder capFinder) throws QueryMetadataException, TeiidComponentException, TeiidProcessingException {
+        BatchedUpdatePlan plan = helpPlan(sql, FakeMetadataFactory.example1Cached(), capFinder, true);
+        List plans = plan.getUpdatePlans();
+        assertEquals("Number of child plans did not match expected", expectedBatching.length, plans.size()); //$NON-NLS-1$
+        for (int i = 0; i < expectedBatching.length; i++) {
+            helpAssertIsBatchedPlan((RelationalPlan)plans.get(i), expectedBatching[i]);
+        }
+    }    
+    
+    public void testPlannerAllCommandsBatched() throws Exception {
+        String[] sql = {"INSERT INTO pm1.g1 (e1, e2, e3, e4) values ('string1', 1, {b'true'}, 1.0)", //$NON-NLS-1$
+                        "INSERT INTO pm1.g2 (e1, e2, e3, e4) values ('string1', 1, {b'true'}, 1.0)", //$NON-NLS-1$
+                        "DELETE FROM pm1.g1 WHERE e2 > 5000", //$NON-NLS-1$
+                        "UPDATE pm1.g1 set e2 = -1 WHERE e2 = 4999" //$NON-NLS-1$
+        };
+        boolean[] expectedBatching = {true};
+        helpTestPlanner(sql, expectedBatching);
+    }
+    
+    public void testPlannerNoCommandsBatched() throws Exception {
+        String[] sql = {"INSERT INTO pm1.g1 (e1, e2, e3, e4) values ('string1', 1, {b'true'}, 1.0)", //$NON-NLS-1$
+                        "INSERT INTO pm1.g2 (e1, e2, e3, e4) values ('string1', 1, {b'true'}, 1.0)", //$NON-NLS-1$
+                        "DELETE FROM pm1.g1 WHERE e2 > 5000", //$NON-NLS-1$
+                        "UPDATE pm1.g1 set e2 = -1 WHERE e2 = 4999" //$NON-NLS-1$
+        };
+        FakeCapabilitiesFinder finder = new FakeCapabilitiesFinder();
+        finder.addCapabilities("pm1", new FakeCapabilities(false)); //$NON-NLS-1$
+        boolean[] expectedBatching = {false, false, false, false};
+        helpTestPlanner(sql, expectedBatching, finder);
+    }
+    
+    public void testPlannerSomeCommandsBatched() throws Exception {
+        String[] sql = {"INSERT INTO pm1.g1 (e1, e2, e3, e4) values ('string1', 1, {b'true'}, 1.0)", //$NON-NLS-1$
+                        "INSERT INTO pm1.g2 (e1, e2, e3, e4) values ('string1', 1, {b'true'}, 1.0)", //$NON-NLS-1$
+                        "DELETE FROM pm2.g1 WHERE e2 > 5000", //$NON-NLS-1$
+                        "INSERT INTO pm2.g1 (e1, e2, e3, e4) values ('5000', 5000, {b'true'}, 5000.0)", //$NON-NLS-1$
+                        "UPDATE pm2.g1 set e2 = -1 WHERE e2 = 4999", //$NON-NLS-1$
+                        "DELETE FROM pm1.g2 WHERE e2 = 50" //$NON-NLS-1$
+        };
+        FakeCapabilitiesFinder finder = new FakeCapabilitiesFinder();
+        finder.addCapabilities("pm1", new FakeCapabilities(false)); //$NON-NLS-1$
+        finder.addCapabilities("pm2", new FakeCapabilities(true)); //$NON-NLS-1$
+        boolean[] expectedBatching = {false, false, true, false};
+        helpTestPlanner(sql, expectedBatching, finder);
+    }
+
+    private static final class FakeCapabilities implements SourceCapabilities {
+        private boolean supportsBatching = false;
+        private FakeCapabilities(boolean supportsBatching) {
+            this.supportsBatching = supportsBatching;
+        }
+        public Scope getScope() {return null;}
+        public boolean supportsCapability(Capability capability) {
+            return !capability.equals(Capability.BATCHED_UPDATES) || supportsBatching;
+        }
+        public boolean supportsFunction(String functionName) {return false;}
+        // since 4.4
+        public Object getSourceProperty(Capability propertyName) {return null;}
+        
+    }
+    
+    private static final boolean DEBUG = false;
+    
+}

Modified: trunk/engine/src/test/java/org/teiid/query/optimizer/TestOptimizer.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/optimizer/TestOptimizer.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/test/java/org/teiid/query/optimizer/TestOptimizer.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -228,7 +228,7 @@
         }
         
         // Collect atomic queries
-        ProcessorPlan plan = getPlan(command, md, capFinder, analysisRecord, mode != ComparisonMode.FAILED_PLANNING);
+        ProcessorPlan plan = getPlan(command, md, capFinder, analysisRecord, mode != ComparisonMode.FAILED_PLANNING, new CommandContext());
                
         if (mode == ComparisonMode.CORRECTED_COMMAND_STRING) {
             checkAtomicQueries(expectedAtomic, plan, md, capFinder);
@@ -279,49 +279,35 @@
         assertEquals("Did not get expected atomic queries: ", expectedQueries, actualQueries); //$NON-NLS-1$
     }
     
-    static ProcessorPlan getPlan(Command command, QueryMetadataInterface md, CapabilitiesFinder capFinder, AnalysisRecord analysisRecord, boolean shouldSucceed) {
-		// plan
+    public static ProcessorPlan getPlan(Command command, QueryMetadataInterface md, CapabilitiesFinder capFinder, AnalysisRecord analysisRecord, boolean shouldSucceed, CommandContext cc) {
 		ProcessorPlan plan = null;
 		if (analysisRecord == null) {
         	analysisRecord = new AnalysisRecord(false, DEBUG);
 		}
-		if (shouldSucceed) {
-			try {
-				//do planning
-				plan = QueryOptimizer.optimizePlan(command, md, null, capFinder, analysisRecord, new CommandContext());
-
-			} catch (Throwable e) {
-				throw new TeiidRuntimeException(e);
-			} finally {
-                if(DEBUG) {
-                    System.out.println(analysisRecord.getDebugLog());
-                }
-			}
-		} else {
-			Exception exception = null;
-			try {
-				//do planning
-				QueryOptimizer.optimizePlan(command, md, null, capFinder, analysisRecord, null);
-
-			} catch (QueryPlannerException e) {
-				exception = e;
-			} catch (TeiidComponentException e) {
-				exception = e;
-			} catch (Throwable e) {
-                throw new TeiidRuntimeException(e);
-            } finally {
-                if(DEBUG) {
-                    System.out.println(analysisRecord.getDebugLog());
-                }
-			}
+		Exception exception = null;
+		try {
+			//do planning
+			plan = QueryOptimizer.optimizePlan(command, md, null, capFinder, analysisRecord, cc);
+		} catch (QueryPlannerException e) {
+			exception = e;
+		} catch (TeiidComponentException e) {
+			exception = e;
+		} catch (Throwable e) {
+			throw new TeiidRuntimeException(e);
+		} finally {
+            if(DEBUG) {
+                System.out.println(analysisRecord.getDebugLog());
+            }
+		}
+		if (!shouldSucceed) {
 			assertNotNull("Expected exception but did not get one.", exception); //$NON-NLS-1$
 			return null;
+		} 
+		if (plan == null) {
+			throw new TeiidRuntimeException(exception);
 		}
-        
-        assertNotNull("Output elements are null", plan.getOutputElements()); //$NON-NLS-1$
-        		
+		assertNotNull("Output elements are null", plan.getOutputElements()); //$NON-NLS-1$
 		if(DEBUG) System.out.println("\n" + plan);	 //$NON-NLS-1$
-		        
 		return plan;
 	}
     

Modified: trunk/engine/src/test/java/org/teiid/query/processor/FakeDataManager.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/FakeDataManager.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/test/java/org/teiid/query/processor/FakeDataManager.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -108,10 +108,10 @@
 		// does nothing?
     } 
 	
-	public TupleSource registerRequest(Object processorID, Command command, String modelName, String connectorBindingId, int nodeID)
+	public TupleSource registerRequest(CommandContext context, Command command, String modelName, String connectorBindingId, int nodeID)
 		throws TeiidComponentException {
         
-        LogManager.logTrace(LOG_CONTEXT, new Object[]{"Register Request:", command, ",processorID:", processorID, ",model name:", modelName,",TupleSourceID nodeID:",new Integer(nodeID)}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+        LogManager.logTrace(LOG_CONTEXT, new Object[]{"Register Request:", command, ",processorID:", context.getProcessorID(), ",model name:", modelName,",TupleSourceID nodeID:",new Integer(nodeID)}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
 
         if (this.recordingCommands) {
             if (! (command instanceof BatchedUpdateCommand) ) {

Modified: trunk/engine/src/test/java/org/teiid/query/processor/HardcodedDataManager.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/HardcodedDataManager.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/test/java/org/teiid/query/processor/HardcodedDataManager.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -110,10 +110,10 @@
     }
     
     /** 
-     * @see org.teiid.query.processor.ProcessorDataManager#registerRequest(java.lang.Object, org.teiid.query.sql.lang.Command, java.lang.String, String, int)
+     * @see org.teiid.query.processor.ProcessorDataManager#registerRequest(CommandContext, org.teiid.query.sql.lang.Command, java.lang.String, String, int)
      * @since 4.2
      */
-    public TupleSource registerRequest(Object processorID,
+    public TupleSource registerRequest(CommandContext context,
                                 Command command,
                                 String modelName,
                                 String connectorBindingId, int nodeID) throws TeiidComponentException {

Copied: trunk/engine/src/test/java/org/teiid/query/processor/TestBatchedUpdatePlan.java (from rev 2390, trunk/engine/src/test/java/org/teiid/query/processor/batch/TestBatchedUpdatePlan.java)
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/TestBatchedUpdatePlan.java	                        (rev 0)
+++ trunk/engine/src/test/java/org/teiid/query/processor/TestBatchedUpdatePlan.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -0,0 +1,85 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.query.processor;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.teiid.common.buffer.TupleBatch;
+import org.teiid.query.processor.BatchedUpdatePlan;
+
+import junit.framework.TestCase;
+
+
+
+/** 
+ * @since 4.2
+ */
+public class TestBatchedUpdatePlan extends TestCase {
+
+	public TestBatchedUpdatePlan(String name) {
+        super(name);
+    }
+    
+    private void helpTestNextBatch(int[] commandsPerPlan) throws Exception {
+        List plans = new ArrayList(commandsPerPlan.length);
+        int totalCommands = 0;
+        for (int i = 0; i < commandsPerPlan.length; i++) {
+            totalCommands += commandsPerPlan[i];
+            plans.add(new FakeProcessorPlan(commandsPerPlan[i]));
+        }
+        BatchedUpdatePlan plan = new BatchedUpdatePlan(plans, totalCommands, null);
+        TupleBatch batch = plan.nextBatch();
+        assertEquals(totalCommands, batch.getRowCount());
+        for (int i = 1; i <= totalCommands; i++) {
+            assertEquals(new Integer(1), batch.getTuple(i).get(0));
+        }
+    }
+    
+    public void testOpen() throws Exception {
+        FakeProcessorPlan[] plans = new FakeProcessorPlan[4];
+        for (int i = 0; i < plans.length; i++) {
+            plans[i] = new FakeProcessorPlan(1);
+        }
+        BatchedUpdatePlan plan = new BatchedUpdatePlan(Arrays.asList(plans), plans.length, null);
+        plan.open();
+        // First plan may or may not be opened, but all subsequent plans should not be opened.
+        for (int i = 1; i < plans.length; i++) {
+            assertFalse(plans[i].isOpened());
+        }
+    }
+
+    public void testNextBatch1() throws Exception {
+        helpTestNextBatch(new int[] {1, 5, 2, 1, 10, 1, 1});
+    }
+    
+    public void testNextBatch2() throws Exception {
+        helpTestNextBatch(new int[] {5, 4, 10, 7, 22, 9, 12, 8, 11});
+    }
+    
+    public void testNextBatch3() throws Exception {
+        helpTestNextBatch(new int[] {1, 1, 1, 1});
+    }
+    
+}

Modified: trunk/engine/src/test/java/org/teiid/query/processor/TestProcedureRelational.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/TestProcedureRelational.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/test/java/org/teiid/query/processor/TestProcedureRelational.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -50,6 +50,7 @@
 import org.teiid.query.unittest.FakeMetadataFactory;
 import org.teiid.query.unittest.FakeMetadataObject;
 import org.teiid.query.unittest.FakeMetadataStore;
+import org.teiid.query.util.CommandContext;
 
 
 public class TestProcedureRelational {
@@ -723,7 +724,7 @@
         // Run query 
         HardcodedDataManager dataManager = new HardcodedDataManager() {
         	@Override
-        	public TupleSource registerRequest(Object processorID,
+        	public TupleSource registerRequest(CommandContext context,
         			Command command, String modelName,
         			String connectorBindingId, int nodeID)
         			throws TeiidComponentException {
@@ -736,7 +737,7 @@
         				Arrays.asList(value+2), Arrays.asList(value+5)
         			});
         		}
-        		return super.registerRequest(processorID, command, modelName,
+        		return super.registerRequest(context, command, modelName,
         				connectorBindingId, nodeID);
         	}
         };

Modified: trunk/engine/src/test/java/org/teiid/query/processor/TestTempTables.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/TestTempTables.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/test/java/org/teiid/query/processor/TestTempTables.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -51,7 +51,7 @@
 	}
 
 	@Before public void setUp() {
-		TempTableStore tempStore = new TempTableStore(BufferManagerFactory.getStandaloneBufferManager(), "1", null); //$NON-NLS-1$
+		TempTableStore tempStore = new TempTableStore(BufferManagerFactory.getStandaloneBufferManager(), "1"); //$NON-NLS-1$
 		metadata = new TempMetadataAdapter(FakeMetadataFactory.example1Cached(), tempStore.getMetadataStore());
 		FakeDataManager fdm = new FakeDataManager();
 	    TestProcessor.sampleData1(fdm);

Modified: trunk/engine/src/test/java/org/teiid/query/processor/relational/TestBatchedUpdateNode.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/relational/TestBatchedUpdateNode.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/test/java/org/teiid/query/processor/relational/TestBatchedUpdateNode.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -37,7 +37,7 @@
 import org.teiid.common.buffer.TupleSource;
 import org.teiid.core.TeiidComponentException;
 import org.teiid.query.metadata.QueryMetadataInterface;
-import org.teiid.query.optimizer.batch.TestBatchedUpdatePlanner;
+import org.teiid.query.optimizer.TestBatchedUpdatePlanner;
 import org.teiid.query.processor.ProcessorDataManager;
 import org.teiid.query.sql.lang.BatchedUpdateCommand;
 import org.teiid.query.sql.lang.Command;
@@ -211,8 +211,8 @@
         	this.numExecutedCommands = numExecutedCommands;
         }
         public Object lookupCodeValue(CommandContext context,String codeTableName,String returnElementName,String keyElementName,Object keyValue) throws BlockedException,TeiidComponentException {return null;}
-        public TupleSource registerRequest(Object processorID,Command command,String modelName,String connectorBindingId, int nodeID) throws TeiidComponentException {
-            assertEquals("myProcessorID", processorID); //$NON-NLS-1$
+        public TupleSource registerRequest(CommandContext context,Command command,String modelName,String connectorBindingId, int nodeID) throws TeiidComponentException {
+            assertEquals("myProcessorID", context.getProcessorID()); //$NON-NLS-1$
             assertEquals("myModelName", modelName); //$NON-NLS-1$
             assertEquals(1, nodeID);
             commands.add(command.toString());

Modified: trunk/engine/src/test/java/org/teiid/query/processor/relational/TestProjectIntoNode.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/relational/TestProjectIntoNode.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/test/java/org/teiid/query/processor/relational/TestProjectIntoNode.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -132,7 +132,7 @@
             this.expectedBatchSize = expectedBatchSize;
         }
         public Object lookupCodeValue(CommandContext context,String codeTableName,String returnElementName,String keyElementName,Object keyValue) throws BlockedException,TeiidComponentException {return null;}
-        public TupleSource registerRequest(Object processorID,Command command,String modelName,String connectorBindingId, int nodeID) throws TeiidComponentException, TeiidProcessingException {
+        public TupleSource registerRequest(CommandContext context,Command command,String modelName,String connectorBindingId, int nodeID) throws TeiidComponentException, TeiidProcessingException {
             callCount++;
             
             int batchSize = 1;

Modified: trunk/engine/src/test/java/org/teiid/query/processor/xml/TestXMLProcessor.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/xml/TestXMLProcessor.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/test/java/org/teiid/query/processor/xml/TestXMLProcessor.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -548,7 +548,7 @@
         List normDocE3 = FakeMetadataFactory.createElements(normDoc3, new String[] { "Catalogs", "Catalogs.Catalog", "Catalogs.Catalog.items", "Catalogs.Catalog.items.item", "Catalogs.Catalog.items.item. at ItemID", "Catalogs.Catalog.items.item.Name", "Catalogs.Catalog.items.item.Quantity", "Catalogs.Catalog.items.DiscontinuedItem", "Catalogs.Catalog.items.DiscontinuedItem. at ItemID", "Catalogs.Catalog.items.DiscontinuedItem.Name", "Catalogs.Catalog.items.DiscontinuedItem.Quantity", "Catalogs.Catalog.items.StatusUnknown", "Catalogs.Catalog.items.StatusUnknown. at ItemID", "Catalogs.Catalog.items.StatusUnknown.Name", "Catalogs.Catalog.items.StatusUnknown.Quantity", "Catalogs.Catalog.items.Shouldn't see", "Catalogs.Catalog.items.Shouldn't see 2" }, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$ //$NON-NLS-11$ //$NON-NLS-12$ //$NON-NLS-13$ //$NON-NLS-14$ //$NON-NLS-15$ //$NON-NLS-16$ //$NON-N!
 LS-17$
                                                             new String[] { DataTypeManager.DefaultDataTypes.STRING, DataTypeManager.DefaultDataTypes.STRING, DataTypeManager.DefaultDataTypes.STRING, DataTypeManager.DefaultDataTypes.STRING, DataTypeManager.DefaultDataTypes.STRING, DataTypeManager.DefaultDataTypes.STRING, DataTypeManager.DefaultDataTypes.INTEGER, DataTypeManager.DefaultDataTypes.STRING, DataTypeManager.DefaultDataTypes.STRING, DataTypeManager.DefaultDataTypes.STRING, DataTypeManager.DefaultDataTypes.INTEGER, DataTypeManager.DefaultDataTypes.STRING, DataTypeManager.DefaultDataTypes.STRING, DataTypeManager.DefaultDataTypes.STRING, DataTypeManager.DefaultDataTypes.INTEGER, DataTypeManager.DefaultDataTypes.STRING, DataTypeManager.DefaultDataTypes.STRING });
         
-        QueryNode vspqn1 = new QueryNode("vsp1", "CREATE VIRTUAL PROCEDURE BEGIN SELECT * FROM xmltest.doc1; END"); //$NON-NLS-1$ //$NON-NLS-2$
+        QueryNode vspqn1 = new QueryNode("vsp1", "CREATE VIRTUAL PROCEDURE BEGIN insert into #temp select * from stock.items; SELECT * FROM xmltest.doc1 where Item.Quantity < (select avg(itemquantity) from #temp); END"); //$NON-NLS-1$ //$NON-NLS-2$
         FakeMetadataObject vsprs1 = FakeMetadataFactory.createResultSet("pm1.vsprs1", xmltest, new String[] { "xml" }, new String[] { DataTypeManager.DefaultDataTypes.XML }); //$NON-NLS-1$ //$NON-NLS-2$
         FakeMetadataObject vspp1 = FakeMetadataFactory.createParameter("ret", 1, ParameterInfo.RESULT_SET, DataTypeManager.DefaultDataTypes.XML, vsprs1); //$NON-NLS-1$
         FakeMetadataObject vsp1 = FakeMetadataFactory.createVirtualProcedure("xmltest.vsp1", xmltest, Arrays.asList(new FakeMetadataObject[] { vspp1 }), vspqn1); //$NON-NLS-1$
@@ -11847,7 +11847,7 @@
     }    
     
     /**
-     * Also tests the logic of the {@link XMLPostProcessor}
+     * Ensures that temp tables are still visible when processing criteria
      */
     @Test public void testProcedureAndXML() throws Exception {
         FakeMetadataFacade metadata = exampleMetadataCached();
@@ -11861,10 +11861,6 @@
             "                <Name>Lamp</Name>\r\n" +  //$NON-NLS-1$
             "                <Quantity>5</Quantity>\r\n" +  //$NON-NLS-1$
             "            </Item>\r\n" +  //$NON-NLS-1$
-            "            <Item ItemID=\"002\">\r\n" +  //$NON-NLS-1$
-            "                <Name>Screwdriver</Name>\r\n" +  //$NON-NLS-1$
-            "                <Quantity>100</Quantity>\r\n" +  //$NON-NLS-1$
-            "            </Item>\r\n" +  //$NON-NLS-1$
             "            <Item ItemID=\"003\">\r\n" +  //$NON-NLS-1$
             "                <Name>Goat</Name>\r\n" +  //$NON-NLS-1$
             "                <Quantity>4</Quantity>\r\n" +  //$NON-NLS-1$
@@ -11872,6 +11868,7 @@
             "        </Items>\r\n" +  //$NON-NLS-1$
             "    </Catalog>\r\n" +  //$NON-NLS-1$
             "</Catalogs>\r\n\r\n"; //$NON-NLS-1$
+        helpTestProcess("call xmltest.vsp1()", expectedDoc, metadata, dataMgr);         //$NON-NLS-1$
     }
     
     /**

Modified: trunk/engine/src/test/java/org/teiid/query/unittest/FakeMetadataFactory.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/unittest/FakeMetadataFactory.java	2010-07-30 20:39:58 UTC (rev 2394)
+++ trunk/engine/src/test/java/org/teiid/query/unittest/FakeMetadataFactory.java	2010-07-31 22:31:31 UTC (rev 2395)
@@ -2127,6 +2127,14 @@
         virtGroup1.putProperty(FakeMetadataObject.Props.MAT_GROUP, physGroup1);
         virtGroup1.putProperty(FakeMetadataObject.Props.MAT_STAGE, physGroupStage1);
 
+        //add one virtual group that uses the materialized group in transformation with NOCACHE option
+        QueryNode vTrans2 = new QueryNode("MatView.VGroup2", "/* cache */ SELECT x FROM matsrc");         //$NON-NLS-1$ //$NON-NLS-2$
+        FakeMetadataObject vGroup2 = createVirtualGroup("MatView.VGroup2", virtModel, vTrans2); //$NON-NLS-1$
+        List vElements2 = createElements(vGroup2,
+                                      new String[] { "x" }, //$NON-NLS-1$
+                                      new String[] { DataTypeManager.DefaultDataTypes.STRING});
+
+        
         FakeMetadataStore store = new FakeMetadataStore();
         store.addObject(virtModel);
         store.addObject(physModel);
@@ -2147,6 +2155,8 @@
         store.addObjects(vElements);
         store.addObject(virtGroup1);
         store.addObjects(virtElements1);
+        store.addObject(vGroup2);
+        store.addObjects(vElements2);
         return new FakeMetadataFacade(store);
     }
     



More information about the teiid-commits mailing list