[teiid-commits] teiid SVN: r2758 - in trunk/engine/src: main/java/org/teiid/query/validator and 3 other directories.

teiid-commits at lists.jboss.org teiid-commits at lists.jboss.org
Mon Dec 6 09:40:10 EST 2010


Author: shawkins
Date: 2010-12-06 09:40:09 -0500 (Mon, 06 Dec 2010)
New Revision: 2758

Modified:
   trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
   trunk/engine/src/main/java/org/teiid/query/validator/UpdateValidator.java
   trunk/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java
   trunk/engine/src/main/resources/org/teiid/query/i18n.properties
   trunk/engine/src/test/java/org/teiid/query/processor/TestInherintlyUpdatableViews.java
   trunk/engine/src/test/java/org/teiid/query/validator/TestUpdateValidator.java
Log:
TEIID-1351 adding union all support inherently updatable views

Modified: trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java	2010-12-03 20:41:42 UTC (rev 2757)
+++ trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java	2010-12-06 14:40:09 UTC (rev 2758)
@@ -2557,63 +2557,15 @@
 	private Command rewriteUpdate(Update update) throws TeiidComponentException, TeiidProcessingException{
 		UpdateInfo info = update.getUpdateInfo();
 		if (info != null && info.isInherentUpdate()) {
-			UpdateMapping mapping = info.findUpdateMapping(update.getChangeList().getClauseMap().keySet(), false);
-			if (mapping == null) {
-				throw new QueryValidatorException(QueryPlugin.Util.getString("ValidationVisitor.nonUpdatable", update.getChangeList().getClauseMap().keySet())); //$NON-NLS-1$
-			}
-			Map<ElementSymbol, ElementSymbol> symbolMap = mapping.getUpdatableViewSymbols();
-			if (info.isSimple()) {
-				update.setGroup(mapping.getGroup().clone());
-				for (SetClause clause : update.getChangeList().getClauses()) {
-					clause.setSymbol(symbolMap.get(clause.getSymbol()));
+			if (!info.getUnionBranches().isEmpty()) {
+				List<Command> batchedUpdates = new ArrayList<Command>(info.getUnionBranches().size() + 1);
+				for (UpdateInfo branchInfo : info.getUnionBranches()) {
+					batchedUpdates.add(createInherentUpdateProc((Update)update.clone(), branchInfo));
 				}
-				//TODO: properly handle correlated references
-				DeepPostOrderNavigator.doVisit(update, new ExpressionMappingVisitor(symbolMap, true));
-				if (info.getViewDefinition().getCriteria() != null) {
-					update.setCriteria(Criteria.combineCriteria(update.getCriteria(), (Criteria)info.getViewDefinition().getCriteria().clone()));
-				}
-				//resolve
-				update.setUpdateInfo(ProcedureContainerResolver.getUpdateInfo(update.getGroup(), metadata));
-				return rewriteUpdate(update);
-			} 
-			Query query = (Query)info.getViewDefinition().clone();
-			query.setOrderBy(null);
-			SymbolMap expressionMapping = SymbolMap.createSymbolMap(update.getGroup(), query.getProjectedSymbols(), metadata);
-			
-			ArrayList<SingleElementSymbol> selectSymbols = new ArrayList<SingleElementSymbol>(update.getChangeList().getClauses().size());
-			int i = 0;
-			for (SetClause clause : update.getChangeList().getClauses()) {
-				Expression ex = clause.getValue();
-				SingleElementSymbol selectSymbol = null;
-				if (!EvaluatableVisitor.willBecomeConstant(ex)) {
-					if (!(ex instanceof SingleElementSymbol)) {
-						selectSymbol = new ExpressionSymbol("expr", ex); //$NON-NLS-1$
-					} else {
-						selectSymbol = (SingleElementSymbol)ex;
-					}
-					selectSymbols.add(new AliasSymbol("s_" +i, selectSymbol)); //$NON-NLS-1$
-					ex = new ElementSymbol("s_" +i); //$NON-NLS-1$
-				}
-				clause.setSymbol(symbolMap.get(clause.getSymbol()));
-				i++;
+				batchedUpdates.add(0, createInherentUpdateProc(update, info));
+				return new BatchedUpdateCommand(batchedUpdates);
 			}
-			query.setSelect(new Select(selectSymbols));
-			ExpressionMappingVisitor emv = new ExpressionMappingVisitor(expressionMapping.asMap(), true);
-			PostOrderNavigator.doVisit(query.getSelect(), emv);
-			
-			Criteria crit = update.getCriteria();
-			if (crit != null) {
-				PostOrderNavigator.doVisit(crit, emv);
-				query.setCriteria(Criteria.combineCriteria(query.getCriteria(), crit));
-			}
-			
-			Update newUpdate = new Update();
-			newUpdate.setChangeList(update.getChangeList());
-			newUpdate.setGroup(mapping.getGroup().clone());
-			
-			List<Criteria> pkCriteria = createPkCriteria(mapping, query, i);
-			newUpdate.setCriteria(Criteria.combineCriteria(newUpdate.getCriteria(), new CompoundCriteria(pkCriteria)));
-			return createUpdateProcedure(update, query, newUpdate);
+			return createInherentUpdateProc(update, info);
 		}
 		
 		if (commandType == Command.TYPE_UPDATE && variables != null) {
@@ -2642,6 +2594,69 @@
 		return update;
 	}
 
+	private Command createInherentUpdateProc(Update update, UpdateInfo info)
+			throws QueryValidatorException, QueryMetadataException,
+			TeiidComponentException, QueryResolverException,
+			TeiidProcessingException {
+		UpdateMapping mapping = info.findUpdateMapping(update.getChangeList().getClauseMap().keySet(), false);
+		if (mapping == null) {
+			throw new QueryValidatorException(QueryPlugin.Util.getString("ValidationVisitor.nonUpdatable", update.getChangeList().getClauseMap().keySet())); //$NON-NLS-1$
+		}
+		Map<ElementSymbol, ElementSymbol> symbolMap = mapping.getUpdatableViewSymbols();
+		if (info.isSimple()) {
+			update.setGroup(mapping.getGroup().clone());
+			for (SetClause clause : update.getChangeList().getClauses()) {
+				clause.setSymbol(symbolMap.get(clause.getSymbol()));
+			}
+			//TODO: properly handle correlated references
+			DeepPostOrderNavigator.doVisit(update, new ExpressionMappingVisitor(symbolMap, true));
+			if (info.getViewDefinition().getCriteria() != null) {
+				update.setCriteria(Criteria.combineCriteria(update.getCriteria(), (Criteria)info.getViewDefinition().getCriteria().clone()));
+			}
+			//resolve
+			update.setUpdateInfo(ProcedureContainerResolver.getUpdateInfo(update.getGroup(), metadata));
+			return rewriteUpdate(update);
+		} 
+		Query query = (Query)info.getViewDefinition().clone();
+		query.setOrderBy(null);
+		SymbolMap expressionMapping = SymbolMap.createSymbolMap(update.getGroup(), query.getProjectedSymbols(), metadata);
+		
+		ArrayList<SingleElementSymbol> selectSymbols = new ArrayList<SingleElementSymbol>(update.getChangeList().getClauses().size());
+		int i = 0;
+		for (SetClause clause : update.getChangeList().getClauses()) {
+			Expression ex = clause.getValue();
+			SingleElementSymbol selectSymbol = null;
+			if (!EvaluatableVisitor.willBecomeConstant(ex)) {
+				if (!(ex instanceof SingleElementSymbol)) {
+					selectSymbol = new ExpressionSymbol("expr", ex); //$NON-NLS-1$
+				} else {
+					selectSymbol = (SingleElementSymbol)ex;
+				}
+				selectSymbols.add(new AliasSymbol("s_" +i, selectSymbol)); //$NON-NLS-1$
+				ex = new ElementSymbol("s_" +i); //$NON-NLS-1$
+			}
+			clause.setSymbol(symbolMap.get(clause.getSymbol()));
+			i++;
+		}
+		query.setSelect(new Select(selectSymbols));
+		ExpressionMappingVisitor emv = new ExpressionMappingVisitor(expressionMapping.asMap(), true);
+		PostOrderNavigator.doVisit(query.getSelect(), emv);
+		
+		Criteria crit = update.getCriteria();
+		if (crit != null) {
+			PostOrderNavigator.doVisit(crit, emv);
+			query.setCriteria(Criteria.combineCriteria(query.getCriteria(), crit));
+		}
+		
+		Update newUpdate = new Update();
+		newUpdate.setChangeList(update.getChangeList());
+		newUpdate.setGroup(mapping.getGroup().clone());
+		
+		List<Criteria> pkCriteria = createPkCriteria(mapping, query, i);
+		newUpdate.setCriteria(Criteria.combineCriteria(newUpdate.getCriteria(), new CompoundCriteria(pkCriteria)));
+		return createUpdateProcedure(update, query, newUpdate);
+	}
+
 	private Command createUpdateProcedure(ProcedureContainer update, Query query,
 			ProcedureContainer newUpdate) throws QueryResolverException,
 			TeiidComponentException, TeiidProcessingException {
@@ -2715,38 +2730,15 @@
 	private Command rewriteDelete(Delete delete) throws TeiidComponentException, TeiidProcessingException{
 		UpdateInfo info = delete.getUpdateInfo();
 		if (info != null && info.isInherentDelete()) {
-			UpdateMapping mapping = info.getDeleteTarget();
-			if (info.isSimple()) {
-				delete.setGroup(mapping.getGroup().clone());
-				//TODO: properly handle correlated references
-				DeepPostOrderNavigator.doVisit(delete, new ExpressionMappingVisitor(mapping.getUpdatableViewSymbols(), true));
-				delete.setUpdateInfo(ProcedureContainerResolver.getUpdateInfo(delete.getGroup(), metadata));
-				if (info.getViewDefinition().getCriteria() != null) {
-					delete.setCriteria(Criteria.combineCriteria(delete.getCriteria(), (Criteria)info.getViewDefinition().getCriteria().clone()));
+			if (!info.getUnionBranches().isEmpty()) {
+				List<Command> batchedUpdates = new ArrayList<Command>(info.getUnionBranches().size() + 1);
+				for (UpdateInfo branchInfo : info.getUnionBranches()) {
+					batchedUpdates.add(createInherentDeleteProc((Delete)delete.clone(), branchInfo));
 				}
-				return rewriteDelete(delete);
+				batchedUpdates.add(0, createInherentDeleteProc(delete, info));
+				return new BatchedUpdateCommand(batchedUpdates);
 			}
-			
-			Query query = (Query)info.getViewDefinition().clone();
-			query.setOrderBy(null);
-			SymbolMap expressionMapping = SymbolMap.createSymbolMap(delete.getGroup(), query.getProjectedSymbols(), metadata);
-			
-			query.setSelect(new Select());
-			ExpressionMappingVisitor emv = new ExpressionMappingVisitor(expressionMapping.asMap(), true);
-			PostOrderNavigator.doVisit(query.getSelect(), emv);
-			
-			Criteria crit = delete.getCriteria();
-			if (crit != null) {
-				PostOrderNavigator.doVisit(crit, emv);
-				query.setCriteria(Criteria.combineCriteria(query.getCriteria(), crit));
-			}
-			
-			Delete newUpdate = new Delete();
-			newUpdate.setGroup(mapping.getGroup().clone());
-			
-			List<Criteria> pkCriteria = createPkCriteria(mapping, query, 0);
-			newUpdate.setCriteria(Criteria.combineCriteria(newUpdate.getCriteria(), new CompoundCriteria(pkCriteria)));
-			return createUpdateProcedure(delete, query, newUpdate);
+			return createInherentDeleteProc(delete, info);
 		}
 		// Rewrite criteria
 		Criteria crit = delete.getCriteria();
@@ -2756,6 +2748,43 @@
 
 		return delete;
 	}
+
+	private Command createInherentDeleteProc(Delete delete, UpdateInfo info)
+			throws QueryMetadataException, TeiidComponentException,
+			QueryResolverException, TeiidProcessingException {
+		UpdateMapping mapping = info.getDeleteTarget();
+		if (info.isSimple()) {
+			delete.setGroup(mapping.getGroup().clone());
+			//TODO: properly handle correlated references
+			DeepPostOrderNavigator.doVisit(delete, new ExpressionMappingVisitor(mapping.getUpdatableViewSymbols(), true));
+			delete.setUpdateInfo(ProcedureContainerResolver.getUpdateInfo(delete.getGroup(), metadata));
+			if (info.getViewDefinition().getCriteria() != null) {
+				delete.setCriteria(Criteria.combineCriteria(delete.getCriteria(), (Criteria)info.getViewDefinition().getCriteria().clone()));
+			}
+			return rewriteDelete(delete);
+		}
+		
+		Query query = (Query)info.getViewDefinition().clone();
+		query.setOrderBy(null);
+		SymbolMap expressionMapping = SymbolMap.createSymbolMap(delete.getGroup(), query.getProjectedSymbols(), metadata);
+		
+		query.setSelect(new Select());
+		ExpressionMappingVisitor emv = new ExpressionMappingVisitor(expressionMapping.asMap(), true);
+		PostOrderNavigator.doVisit(query.getSelect(), emv);
+		
+		Criteria crit = delete.getCriteria();
+		if (crit != null) {
+			PostOrderNavigator.doVisit(crit, emv);
+			query.setCriteria(Criteria.combineCriteria(query.getCriteria(), crit));
+		}
+		
+		Delete newUpdate = new Delete();
+		newUpdate.setGroup(mapping.getGroup().clone());
+		
+		List<Criteria> pkCriteria = createPkCriteria(mapping, query, 0);
+		newUpdate.setCriteria(Criteria.combineCriteria(newUpdate.getCriteria(), new CompoundCriteria(pkCriteria)));
+		return createUpdateProcedure(delete, query, newUpdate);
+	}
     
     private Limit rewriteLimitClause(Limit limit) throws TeiidComponentException, TeiidProcessingException{
         if (limit.getOffset() != null) {

Modified: trunk/engine/src/main/java/org/teiid/query/validator/UpdateValidator.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/validator/UpdateValidator.java	2010-12-03 20:41:42 UTC (rev 2757)
+++ trunk/engine/src/main/java/org/teiid/query/validator/UpdateValidator.java	2010-12-06 14:40:09 UTC (rev 2758)
@@ -25,6 +25,7 @@
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 
@@ -38,6 +39,7 @@
 import org.teiid.query.resolver.util.ResolverUtil;
 import org.teiid.query.sql.lang.Command;
 import org.teiid.query.sql.lang.Query;
+import org.teiid.query.sql.lang.QueryCommand;
 import org.teiid.query.sql.lang.SetQuery;
 import org.teiid.query.sql.lang.UnaryFromClause;
 import org.teiid.query.sql.lang.SetQuery.Operation;
@@ -109,6 +111,7 @@
 		private UpdateType insertType;
 		private boolean insertValidationError;
 		private Query view;
+		private List<UpdateInfo> unionBranches = new LinkedList<UpdateInfo>();
 		
 		public boolean isSimple() {
 			return isSimple;
@@ -118,10 +121,6 @@
 			return deleteTarget;
 		}
 		
-		public Map<String, UpdateMapping> getUpdatableGroups() {
-			return updatableGroups;
-		}
-		
 		public boolean isInherentDelete() {
 			return deleteType == UpdateType.INHERENT;
 		}
@@ -142,8 +141,20 @@
 			return deleteType;
 		}
 		
+		public boolean hasValidUpdateMapping(Collection<ElementSymbol> updateCols) {
+			if (findUpdateMapping(updateCols, false) == null) {
+				return false;
+			}
+			for (UpdateInfo info : this.unionBranches) {
+				if (info.findUpdateMapping(updateCols, false) == null) {
+					return false;
+				}
+			}
+			return true;
+		}
+		
 		public UpdateMapping findUpdateMapping(Collection<ElementSymbol> updateCols, boolean insert) {
-			for (UpdateMapping entry : getUpdatableGroups().values()) {
+			for (UpdateMapping entry : this.updatableGroups.values()) {
 				if (((insert && entry.insertAllowed) || (!insert && entry.updateAllowed)) && entry.updatableViewSymbols.keySet().containsAll(updateCols)) {
 					return entry;
 				}
@@ -167,6 +178,10 @@
 			return updateValidationError;
 		}
 		
+		public List<UpdateInfo> getUnionBranches() {
+			return unionBranches;
+		}
+		
 	}
 	
 	private QueryMetadataInterface metadata;
@@ -218,12 +233,9 @@
         		handleValidationError(QueryPlugin.Util.getString("ERR.015.012.0001"), true, true, true); //$NON-NLS-1$
         		return;
         	}
-        	//TOOD each branch should return it's own info?
-        	/*this.validate(setQuery.getLeftQuery(), viewSymbols);
-        	this.validate(setQuery.getRightQuery(), viewSymbols);
-        	if (!this.updateInfo.insertValidationError) {
-        		handleValidationError(QueryPlugin.Util.getString("ERR.015.012.0018"), false, true, false); //$NON-NLS-1$
-        	}*/
+        	validateBranch(viewSymbols, setQuery.getLeftQuery());
+        	validateBranch(viewSymbols, setQuery.getRightQuery());
+        	return;
     	}
     	
     	if (!(command instanceof Query)) {
@@ -351,6 +363,35 @@
     		}
     	}
     }
+
+	private void validateBranch(List<ElementSymbol> viewSymbols,
+			QueryCommand query) throws QueryMetadataException,
+			TeiidComponentException {
+		if (!this.updateInfo.insertValidationError) {
+    		handleValidationError(QueryPlugin.Util.getString("ERR.015.012.0018"), false, true, false); //$NON-NLS-1$
+    	}
+		if (!this.updateInfo.isInherentDelete() && !this.updateInfo.isInherentUpdate()) {
+			return; //don't bother
+		}
+		UpdateValidator uv = this;
+		if (this.updateInfo.view != null) {
+			uv = new UpdateValidator(metadata, null, null, null);
+			uv.updateInfo.deleteType = this.updateInfo.deleteType;
+			uv.updateInfo.insertType = this.updateInfo.insertType;
+			uv.updateInfo.updateType = this.updateInfo.updateType;
+		}
+		uv.validate(query, viewSymbols);
+		if (uv != this) {
+			UpdateInfo info = uv.getUpdateInfo();
+			this.updateInfo.deleteValidationError |= info.deleteValidationError;
+			this.updateInfo.updateValidationError |= info.updateValidationError;
+			if (info.view != null) {
+				this.updateInfo.unionBranches.add(info);
+			} else {
+				this.updateInfo.unionBranches.addAll(info.unionBranches);
+			}
+		}
+	}
     
     private void setUpdateFlags(GroupSymbol groupSymbol) throws QueryMetadataException, TeiidComponentException {
     	UpdateMapping info = updateInfo.updatableGroups.get(groupSymbol.getCanonicalName());

Modified: trunk/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java	2010-12-03 20:41:42 UTC (rev 2757)
+++ trunk/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java	2010-12-06 14:40:09 UTC (rev 2758)
@@ -949,7 +949,7 @@
 		    }
             if (info != null && info.isInherentUpdate()) {
             	Set<ElementSymbol> updateCols = update.getChangeList().getClauseMap().keySet();
-            	if (info.findUpdateMapping(updateCols, false) == null) {
+            	if (!info.hasValidUpdateMapping(updateCols)) {
             		handleValidationError(QueryPlugin.Util.getString("ValidationVisitor.nonUpdatable", updateCols), update); //$NON-NLS-1$
             	}
             }
@@ -1473,7 +1473,7 @@
     	validateSubquery(obj);
     }
 
-    //TODO: it may be simplier to catch this in the parser
+    //TODO: it may be simpler to catch this in the parser
     private void validateSubquery(SubqueryContainer subQuery) {
     	if (subQuery.getCommand() instanceof Query && ((Query)subQuery.getCommand()).getInto() != null) {
         	handleValidationError(QueryPlugin.Util.getString("ValidationVisitor.subquery_insert"), subQuery.getCommand()); //$NON-NLS-1$

Modified: trunk/engine/src/main/resources/org/teiid/query/i18n.properties
===================================================================
--- trunk/engine/src/main/resources/org/teiid/query/i18n.properties	2010-12-03 20:41:42 UTC (rev 2757)
+++ trunk/engine/src/main/resources/org/teiid/query/i18n.properties	2010-12-06 14:40:09 UTC (rev 2758)
@@ -165,7 +165,7 @@
 # util (011)
 
 # validator (012)
-ERR.015.012.0001 = The query defining an updatable view must be a simple query with a FROM clause.
+ERR.015.012.0001 = The query defining an updatable view must be a simple query or a UNION ALL of simple queries.
 ERR.015.012.0002 = The query defining an updatable view has a WITH clause, pass-through processing will not be used for UPDATE/DELETE operations.
 ERR.015.012.0003 = The query defining an updatable view projects a column from a non-updatable group {0}.
 ERR.015.012.0004 = The query defining an updatable view has a non key preserving join group {0}, which cannot be targeted by UPDATE/DELETE operations.

Modified: trunk/engine/src/test/java/org/teiid/query/processor/TestInherintlyUpdatableViews.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/TestInherintlyUpdatableViews.java	2010-12-03 20:41:42 UTC (rev 2757)
+++ trunk/engine/src/test/java/org/teiid/query/processor/TestInherintlyUpdatableViews.java	2010-12-06 14:40:09 UTC (rev 2758)
@@ -22,6 +22,7 @@
 
 package org.teiid.query.processor;
 
+import static org.junit.Assert.*;
 import static org.teiid.query.processor.TestProcessor.*;
 
 import java.util.Arrays;
@@ -33,6 +34,7 @@
 import org.teiid.query.optimizer.capabilities.BasicSourceCapabilities;
 import org.teiid.query.optimizer.capabilities.DefaultCapabilitiesFinder;
 import org.teiid.query.rewriter.TestQueryRewriter;
+import org.teiid.query.sql.lang.BatchedUpdateCommand;
 import org.teiid.query.sql.lang.Command;
 import org.teiid.query.util.CommandContext;
 import org.teiid.query.validator.TestUpdateValidator;
@@ -48,7 +50,7 @@
         helpTest(userSql, viewSql, expectedSql, null);	
 	}
 
-	private void helpTest(String userSql, String viewSql, String expectedSql, ProcessorDataManager dm)
+	private Command helpTest(String userSql, String viewSql, String expectedSql, ProcessorDataManager dm)
 			throws Exception {
 		TransformationMetadata metadata = TestUpdateValidator.example1();
         TestUpdateValidator.createView(viewSql, metadata, "gx");
@@ -62,6 +64,8 @@
 	        List[] expected = new List[] {Arrays.asList(1)};
         	helpProcess(plan, context, dm, expected);
         }
+        
+        return command;
 	}
 	
 	@Test public void testUpdatePassThroughWithAlias() throws Exception {
@@ -85,6 +89,14 @@
         helpTest(userSql, viewSql, expectedSql, null);
 	}
 	
+	@Test public void testDeleteUnion() throws Exception {
+		String userSql = "delete from vm1.gx where e4 is null"; //$NON-NLS-1$
+    	String viewSql = "select * from pm1.g1 where e3 < 5 union all select * from pm1.g2 where e1 > 1";
+        String expectedSql = "BatchedUpdate{D,D}";
+        BatchedUpdateCommand buc = (BatchedUpdateCommand)helpTest(userSql, viewSql, expectedSql, null);
+        assertEquals("DELETE FROM pm1.g2 WHERE (pm1.g2.e4 IS NULL) AND (e1 > '1')", buc.getUpdateCommands().get(1).toString());
+	}
+	
 	/**
 	 * Here we should be able to figure out that we can pass through the join
 	 * @throws Exception

Modified: trunk/engine/src/test/java/org/teiid/query/validator/TestUpdateValidator.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/validator/TestUpdateValidator.java	2010-12-03 20:41:42 UTC (rev 2757)
+++ trunk/engine/src/test/java/org/teiid/query/validator/TestUpdateValidator.java	2010-12-06 14:40:09 UTC (rev 2758)
@@ -55,8 +55,12 @@
 
 @SuppressWarnings("nls")
 public class TestUpdateValidator {
+
+	private UpdateValidator helpTest(String sql, TransformationMetadata md, boolean shouldFail) {
+		return helpTest(sql, md, shouldFail, shouldFail, shouldFail);
+	}
 	
-	private UpdateValidator helpTest(String sql, TransformationMetadata md, boolean shouldFail) { 	
+	private UpdateValidator helpTest(String sql, TransformationMetadata md, boolean failInsert, boolean failUpdate, boolean failDelete) { 	
 		try {
 			String vGroup = "gx";
 			Command command = createView(sql, md, vGroup);
@@ -66,10 +70,9 @@
 			ResolverUtil.resolveGroup(gs, md);
 			uv.validate(command, ResolverUtil.resolveElementsInGroup(gs, md));
 			UpdateInfo info = uv.getUpdateInfo();
-			boolean failed = info.isDeleteValidationError() || info.isInsertValidationError() || info.isUpdateValidationError();
-			if (!failed && shouldFail) {
-				fail("expeceted failures, but got none: " + uv.getReport());
-			}
+			assertEquals(uv.getReport().getFailureMessage(), failInsert, info.isInsertValidationError());
+			assertEquals(uv.getReport().getFailureMessage(), failUpdate, info.isUpdateValidationError());
+			assertEquals(uv.getReport().getFailureMessage(), failDelete, info.isDeleteValidationError());
 			return uv;
 		} catch (TeiidException e) {
 			throw new RuntimeException(e);
@@ -288,37 +291,31 @@
             example1(), true);
     }    
     
-    // Check that e3 is not required (it has a default value)
     @Test public void testRequiredElements1() {
         helpTest("SELECT e1, e2 FROM pm1.g3",
             example1(), false); //$NON-NLS-1$
     }
 
-    // Check that e2 is not required (it is auto-incremented)
     @Test public void testRequiredElements2() {
         helpTest("SELECT e1, e3 FROM pm1.g3",
             example1(), false); //$NON-NLS-1$
     }
 
-    // Check that e1 is required (it is not-nullable, not auto-incrementable, and has no default value)
     @Test public void testRequiredElements3() {
         helpTest("SELECT e2, e3 FROM pm1.g3",
-            example1(), true);
+            example1(), true, false, false);
     }
 
-    // Verify that elements that are not updateable are exlcluded from update and delete procedures
     @Test public void testNonUpdateableElements() {
         helpTest("select e1 as a, e2 from pm1.g1 where e4 > 5", 
                     example1(false), false); //$NON-NLS-1$
 	}
 	
-    // Verify that elements that are not updateable are exlcluded from update and delete procedures
     @Test public void testNonUpdateableElements2() {
         helpTest("SELECT e1, e2 FROM pm1.g1",
             example1(false), false); //$NON-NLS-1$
     }
     
-    // Verify that elements that are not updateable are exlcluded from update and delete procedures
     @Test public void testSelectDistinct() {
         helpTest("SELECT distinct e1, e2 FROM pm1.g1",
             example1(), true); //$NON-NLS-1$
@@ -333,6 +330,11 @@
         helpTest("SELECT g1.e1, x.e2 FROM pm1.g2 x inner join pm1.g1 on (x.e1 = g1.e1)",
             example1(), false); //$NON-NLS-1$
     }
+    
+    @Test public void testUnionAll() {
+        helpTest("SELECT g1.e1, x.e2 FROM pm1.g2 x inner join pm1.g1 on (x.e1 = g1.e1) union all select pm1.g2.e1, pm1.g2.e2 from pm1.g2",
+            example1(), true, false, false); //$NON-NLS-1$
+    }
 
 }
 



More information about the teiid-commits mailing list