[teiid-commits] teiid SVN: r2756 - 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
Fri Dec 3 15:32:46 EST 2010


Author: shawkins
Date: 2010-12-03 15:32:45 -0500 (Fri, 03 Dec 2010)
New Revision: 2756

Modified:
   trunk/engine/src/main/java/org/teiid/query/resolver/ProcedureContainerResolver.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/TestTriggerActions.java
   trunk/engine/src/test/java/org/teiid/query/validator/TestUpdateValidator.java
Log:
TEIID-1351 differentiating between update procedures and trigger actions

Modified: trunk/engine/src/main/java/org/teiid/query/resolver/ProcedureContainerResolver.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/resolver/ProcedureContainerResolver.java	2010-12-03 18:49:01 UTC (rev 2755)
+++ trunk/engine/src/main/java/org/teiid/query/resolver/ProcedureContainerResolver.java	2010-12-03 20:32:45 UTC (rev 2756)
@@ -249,24 +249,23 @@
 	}
 	
 	public static UpdateInfo getUpdateInfo(GroupSymbol group, QueryMetadataInterface metadata) throws QueryMetadataException, TeiidComponentException, QueryResolverException {
-		//if this is not inherently updatable, just return null
-		if(group.isTempGroupSymbol() || !metadata.isVirtualGroup(group.getMetadataID()) || (
-				metadata.getUpdatePlan(group.getMetadataID()) != null && 
-				metadata.getDeletePlan(group.getMetadataID()) != null && 
-				metadata.getInsertPlan(group.getMetadataID()) != null)) {
+		//if this is not a view, just return null
+		if(group.isTempGroupSymbol() || !metadata.isVirtualGroup(group.getMetadataID())) {
 			return null;
 		}
+		String updatePlan = metadata.getUpdatePlan(group.getMetadataID());
+		String deletePlan = metadata.getDeletePlan(group.getMetadataID());
+		String insertPlan = metadata.getInsertPlan(group.getMetadataID());
+
+		
     	UpdateInfo info = (UpdateInfo)metadata.getFromMetadataCache(group.getMetadataID(), "UpdateInfo"); //$NON-NLS-1$
     	if (info == null) {
-    		
             List<ElementSymbol> elements = ResolverUtil.resolveElementsInGroup(group, metadata);
-
-    		UpdateValidator validator = new UpdateValidator(metadata, 
-    				metadata.getUpdatePlan(group.getMetadataID()) == null, 
-    				metadata.getDeletePlan(group.getMetadataID()) == null, 
-    				metadata.getInsertPlan(group.getMetadataID()) == null);
-    		validator.validate(UpdateProcedureResolver.getQueryTransformCmd(group, metadata), elements);
+    		UpdateValidator validator = new UpdateValidator(metadata, updatePlan, deletePlan, insertPlan);
     		info = validator.getUpdateInfo();
+    		if (info.isInherentDelete() || info.isInherentInsert() || info.isInherentUpdate()) {
+    			validator.validate(UpdateProcedureResolver.getQueryTransformCmd(group, metadata), elements);
+    		}
     		metadata.addToMetadataCache(group.getMetadataID(), "UpdateInfo", info); //$NON-NLS-1$
     	}
     	return info;

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 18:49:01 UTC (rev 2755)
+++ trunk/engine/src/main/java/org/teiid/query/validator/UpdateValidator.java	2010-12-03 20:32:45 UTC (rev 2756)
@@ -30,13 +30,17 @@
 
 import org.teiid.api.exception.query.QueryMetadataException;
 import org.teiid.core.TeiidComponentException;
+import org.teiid.core.util.StringUtil;
+import org.teiid.language.SQLConstants;
 import org.teiid.query.QueryPlugin;
 import org.teiid.query.metadata.QueryMetadataInterface;
 import org.teiid.query.metadata.SupportConstants;
 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.SetQuery;
 import org.teiid.query.sql.lang.UnaryFromClause;
+import org.teiid.query.sql.lang.SetQuery.Operation;
 import org.teiid.query.sql.symbol.ElementSymbol;
 import org.teiid.query.sql.symbol.Expression;
 import org.teiid.query.sql.symbol.GroupSymbol;
@@ -51,6 +55,21 @@
  */
 public class UpdateValidator {
 	
+	public enum UpdateType {
+		/**
+		 * The default handling should be used
+		 */
+		INHERENT, 
+		/**
+		 * A procedure handler has been defined
+		 */
+		UPDATE_PROCEDURE,
+		/**
+		 * An instead of trigger (TriggerAction) has been defined
+		 */
+		INSTEAD_OF
+	}
+	
 	public static class UpdateMapping {
 		private GroupSymbol group;
 		private GroupSymbol correlatedName;
@@ -83,11 +102,11 @@
 		private Map<String, UpdateMapping> updatableGroups = new HashMap<String, UpdateMapping>();
 		private boolean isSimple = true;
 		private UpdateMapping deleteTarget;
-		private boolean inherentUpdate;
+		private UpdateType updateType;
 		private boolean updateValidationError;
-		private boolean inherentDelete;
+		private UpdateType deleteType;
 		private boolean deleteValidationError;
-		private boolean inherentInsert;
+		private UpdateType insertType;
 		private boolean insertValidationError;
 		private Query view;
 		
@@ -104,17 +123,25 @@
 		}
 		
 		public boolean isInherentDelete() {
-			return inherentDelete;
+			return deleteType == UpdateType.INHERENT;
 		}
 		
 		public boolean isInherentInsert() {
-			return inherentInsert;
+			return insertType == UpdateType.INHERENT;
 		}
 		
 		public boolean isInherentUpdate() {
-			return inherentUpdate;
+			return updateType == UpdateType.INHERENT;
 		}
 		
+		public UpdateType getUpdateType() {
+			return updateType;
+		}
+		
+		public UpdateType getDeleteType() {
+			return deleteType;
+		}
+		
 		public UpdateMapping findUpdateMapping(Collection<ElementSymbol> updateCols, boolean insert) {
 			for (UpdateMapping entry : getUpdatableGroups().values()) {
 				if (((insert && entry.insertAllowed) || (!insert && entry.updateAllowed)) && entry.updatableViewSymbols.keySet().containsAll(updateCols)) {
@@ -146,12 +173,24 @@
 	private ValidatorReport report = new ValidatorReport();
 	private UpdateInfo updateInfo = new UpdateInfo();
 
-	public UpdateValidator(QueryMetadataInterface qmi, boolean inherentUpdate, boolean inherentDelete, boolean inherentInsert) {
+	public UpdateValidator(QueryMetadataInterface qmi, String updatePlan, String deletePlan, String insertPlan) {
 		this.metadata = qmi;
-		this.updateInfo.inherentDelete = inherentDelete;
-		this.updateInfo.inherentInsert = inherentInsert;
-		this.updateInfo.inherentUpdate = inherentUpdate;
+		this.updateInfo.deleteType = determineType(deletePlan);
+		this.updateInfo.insertType = determineType(insertPlan);
+		this.updateInfo.updateType = determineType(updatePlan);
 	}
+
+	private UpdateType determineType(String plan) {
+		UpdateType type = UpdateType.INHERENT;
+		if (plan != null) {
+			if (StringUtil.startsWithIgnoreCase(plan, SQLConstants.Reserved.CREATE)) {
+				type = UpdateType.UPDATE_PROCEDURE;
+			} else {
+				type = UpdateType.INSTEAD_OF;
+			}
+		}
+		return type;
+	}
 	
 	public UpdateInfo getUpdateInfo() {
 		return updateInfo;
@@ -169,6 +208,24 @@
 	}
 	
     public void validate(Command command, List<ElementSymbol> viewSymbols) throws QueryMetadataException, TeiidComponentException {
+    	if (command instanceof SetQuery) {
+    		SetQuery setQuery = (SetQuery)command;
+        	if (setQuery.getLimit() != null) {
+        		handleValidationError(QueryPlugin.Util.getString("ERR.015.012.0013"), true, true, true); //$NON-NLS-1$
+        		return;
+        	}
+        	if (setQuery.getOperation() != Operation.UNION || !setQuery.isAll()) {
+        		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$
+        	}*/
+    	}
+    	
     	if (!(command instanceof Query)) {
     		handleValidationError(QueryPlugin.Util.getString("ERR.015.012.0001"), true, true, true); //$NON-NLS-1$
     		return;
@@ -191,8 +248,6 @@
     		return;
     	}
     	
-    	updateInfo.view = query;
-    	
     	if (query.getLimit() != null) {
     		handleValidationError(QueryPlugin.Util.getString("ERR.015.012.0013"), true, true, true); //$NON-NLS-1$
     		return;
@@ -203,6 +258,8 @@
     		return;
     	} 
     	
+    	updateInfo.view = query;
+    	
     	List<SingleElementSymbol> projectedSymbols = query.getSelect().getProjectedSymbols();
     	
     	for (int i = 0; i < projectedSymbols.size(); i++) {
@@ -256,7 +313,7 @@
 			if (!allGroups.isEmpty()) {
 				setUpdateFlags(allGroups.iterator().next());
 			}
-		} else if (this.updateInfo.inherentUpdate || this.updateInfo.inherentDelete) {
+		} else if (this.updateInfo.updateType == UpdateType.INHERENT || this.updateInfo.deleteType == UpdateType.INHERENT) {
 			for (GroupSymbol groupSymbol : allGroups) {
 				UpdateMapping info = updateInfo.updatableGroups.get(groupSymbol.getCanonicalName());
 				if (info == null) {
@@ -280,13 +337,13 @@
     		updatable |= info.updateAllowed;
     		insertable |= info.insertAllowed;
     	}
-    	if ((this.updateInfo.inherentInsert && !insertable)) {
+    	if ((this.updateInfo.insertType == UpdateType.INHERENT && !insertable)) {
     		handleValidationError(QueryPlugin.Util.getString("ERR.015.012.0015"), false, true, false); //$NON-NLS-1$
     	} 
-    	if (this.updateInfo.inherentUpdate && !updatable) {
+    	if (this.updateInfo.updateType == UpdateType.INHERENT && !updatable) {
     		handleValidationError(QueryPlugin.Util.getString("ERR.015.012.0005"), true, false, true); //$NON-NLS-1$
     	}
-    	if (this.updateInfo.inherentDelete && this.updateInfo.deleteTarget == null) {
+    	if (this.updateInfo.deleteType == UpdateType.INHERENT && this.updateInfo.deleteTarget == null) {
     		if (this.updateInfo.isSimple) {
     			this.updateInfo.deleteTarget = this.updateInfo.updatableGroups.values().iterator().next();
     		} else {
@@ -330,7 +387,7 @@
 			|| metadata.elementSupports(element.getMetadataID(), SupportConstants.Element.AUTO_INCREMENT)) {
 			return true;
 		}
-		if (this.updateInfo.inherentInsert) {
+		if (this.updateInfo.insertType == UpdateType.INHERENT) {
 			report.handleValidationError(QueryPlugin.Util.getString("ERR.015.012.0010", element, element.getGroupSymbol())); //$NON-NLS-1$
 		}
 	    return false;

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 18:49:01 UTC (rev 2755)
+++ trunk/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java	2010-12-03 20:32:45 UTC (rev 2756)
@@ -76,6 +76,7 @@
 import org.teiid.query.sql.lang.Option;
 import org.teiid.query.sql.lang.OrderBy;
 import org.teiid.query.sql.lang.OrderByItem;
+import org.teiid.query.sql.lang.ProcedureContainer;
 import org.teiid.query.sql.lang.Query;
 import org.teiid.query.sql.lang.QueryCommand;
 import org.teiid.query.sql.lang.SPParameter;
@@ -137,6 +138,7 @@
 import org.teiid.query.sql.visitor.SQLStringVisitor;
 import org.teiid.query.sql.visitor.ValueIteratorProviderCollectorVisitor;
 import org.teiid.query.validator.UpdateValidator.UpdateInfo;
+import org.teiid.query.validator.UpdateValidator.UpdateType;
 import org.teiid.query.xquery.saxon.SaxonXQueryExpression;
 import org.teiid.translator.SourceSystemFunctions;
 
@@ -201,24 +203,20 @@
     	validateNoXMLUpdates(obj);
         GroupSymbol group = obj.getGroup();
         validateGroupSupportsUpdate(group);
-        if (obj.getUpdateInfo() == null || !obj.getUpdateInfo().isInherentDelete()) {
-            Criteria crit = obj.getCriteria();
-        	validateVirtualUpdate(group, crit);
-        }
+        Criteria crit = obj.getCriteria();
+    	validateVirtualUpdate(obj, crit);
     }
 
-	private void validateVirtualUpdate(GroupSymbol group,
+	private void validateVirtualUpdate(ProcedureContainer container, 
 			Criteria crit) {
-		if (crit == null) {
-			return;
+		if (crit == null || container.getUpdateInfo() == null) {
+			return; 
 		}
-		try {
-			if (getMetadata().isVirtualGroup(group.getMetadataID()) && 
-					!ValueIteratorProviderCollectorVisitor.getValueIteratorProviders(crit).isEmpty()) {
+		if ((container.getType() == Command.TYPE_UPDATE && container.getUpdateInfo().getUpdateType() == UpdateType.UPDATE_PROCEDURE) 
+				|| (container.getType() == Command.TYPE_DELETE && container.getUpdateInfo().getDeleteType() == UpdateType.UPDATE_PROCEDURE)) {
+			if (!ValueIteratorProviderCollectorVisitor.getValueIteratorProviders(crit).isEmpty()) {
 				handleValidationError(QueryPlugin.Util.getString("ValidationVisitor.virtual_update_subquery"), crit); //$NON-NLS-1$
 			}
-		} catch (TeiidException e) {
-			handleException(e);
 		}
 	}
 
@@ -335,9 +333,7 @@
         validateNoXMLUpdates(obj);
         validateGroupSupportsUpdate(obj.getGroup());
         validateUpdate(obj);
-        if (obj.getUpdateInfo() == null || !obj.getUpdateInfo().isInherentUpdate()) {
-        	validateVirtualUpdate(obj.getGroup(), obj.getCriteria());
-        }
+    	validateVirtualUpdate(obj, obj.getCriteria());
     }
 
     public void visit(Into obj) {
@@ -911,7 +907,6 @@
     protected void validateUpdate(Update update) {
         try {
             UpdateInfo info = update.getUpdateInfo();
-            boolean updatableView = info != null && info.isInherentUpdate();
 
             // list of elements that are being updated
 		    for (SetClause entry : update.getChangeList().getClauses()) {
@@ -942,7 +937,7 @@
                     if(((Constant)value).isNull() && ! getMetadata().elementSupports(elementID.getMetadataID(), SupportConstants.Element.NULL)) {
                         handleValidationError(QueryPlugin.Util.getString("ERR.015.012.0060", SQLStringVisitor.getSQLString(elementID)), elementID); //$NON-NLS-1$
                     }// end of if
-                } else if (!updatableView && getMetadata().isVirtualGroup(update.getGroup().getMetadataID()) && !EvaluatableVisitor.willBecomeConstant(value)) {
+                } else if (info != null && info.getUpdateType() == UpdateType.UPDATE_PROCEDURE && getMetadata().isVirtualGroup(update.getGroup().getMetadataID()) && !EvaluatableVisitor.willBecomeConstant(value)) {
                     // If this is an update on a virtual group, verify that no elements are in the right side
                     Collection<ElementSymbol> elements = ElementCollectorVisitor.getElements(value, false);
                     for (ElementSymbol element : elements) {
@@ -952,7 +947,7 @@
                     }
                 } 
 		    }
-            if (updatableView) {
+            if (info != null && info.isInherentUpdate()) {
             	Set<ElementSymbol> updateCols = update.getChangeList().getClauseMap().keySet();
             	if (info.findUpdateMapping(updateCols, false) == null) {
             		handleValidationError(QueryPlugin.Util.getString("ValidationVisitor.nonUpdatable", updateCols), update); //$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 18:49:01 UTC (rev 2755)
+++ trunk/engine/src/main/resources/org/teiid/query/i18n.properties	2010-12-03 20:32:45 UTC (rev 2756)
@@ -182,6 +182,7 @@
 ERR.015.012.0015 = The query defining an updatable view has no valid target for INSERTs.
 ERR.015.012.0016 = Variable {0} not assigned any value in this procedure.
 ERR.015.012.0017 = Variables declared the procedure''s DeclareStatement cannot be one of the special variables: {0}, {1} and {2}.
+ERR.015.012.0018 = Inherent INSERT is not possible on a view defined by a UNION.
 ERR.015.012.0019 = TranslateCriteria cannot be used in on an if or while statement.
 ERR.015.012.0020 = Elements used on the criteria of an if or while statement should be variables declared in the procedure, virtual group elements can be used in the HAS Criteria
 ERR.015.012.0021 = Element being translated in the WITH clause not among the elements on the ON clause of the TranslateCriteria.

Modified: trunk/engine/src/test/java/org/teiid/query/processor/TestTriggerActions.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/TestTriggerActions.java	2010-12-03 18:49:01 UTC (rev 2755)
+++ trunk/engine/src/test/java/org/teiid/query/processor/TestTriggerActions.java	2010-12-03 20:32:45 UTC (rev 2756)
@@ -120,5 +120,26 @@
     	helpProcess(plan, context, dm, expected);
     	assertEquals("UPDATE pm1.g1 SET e2 = 5 WHERE e2 = 2", dm.getQueries().get(0));
 	}
+	
+	@Test public void testUpdateWithNonConstant() throws Exception {
+		TransformationMetadata metadata = TestUpdateValidator.example1();
+		TestUpdateValidator.createView("select 1 as x, 2 as y", metadata, "gx");
+		Table t = metadata.getMetadataStore().getSchemas().get("vm1").getTables().get("gx");
+		t.setDeletePlan("");
+		t.setUpdatePlan("FOR EACH ROW BEGIN update pm1.g1 set e2 = new.y where e2 = old.y; END");
+		t.setInsertPlan("");
+		
+		String sql = "update gx set y = x";
+		
+		FakeDataManager dm = new FakeDataManager();
+		FakeDataStore.addTable("pm1.g1", dm, metadata);
+		
+		CommandContext context = createCommandContext();
+        BasicSourceCapabilities caps = TestOptimizer.getTypicalCapabilities();
+        ProcessorPlan plan = TestProcessor.helpGetPlan(TestResolver.helpResolve(sql, metadata, null), metadata, new DefaultCapabilitiesFinder(caps), context);
+        List[] expected = new List[] {Arrays.asList(1)};
+    	helpProcess(plan, context, dm, expected);
+    	assertEquals("UPDATE pm1.g1 SET e2 = 1 WHERE e2 = 2", dm.getQueries().get(0));
+	}
     
 }

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 18:49:01 UTC (rev 2755)
+++ trunk/engine/src/test/java/org/teiid/query/validator/TestUpdateValidator.java	2010-12-03 20:32:45 UTC (rev 2756)
@@ -61,7 +61,7 @@
 			String vGroup = "gx";
 			Command command = createView(sql, md, vGroup);
 			
-			UpdateValidator uv = new UpdateValidator(md, true, true, true);
+			UpdateValidator uv = new UpdateValidator(md, null, null, null);
 			GroupSymbol gs = new GroupSymbol(vGroup);
 			ResolverUtil.resolveGroup(gs, md);
 			uv.validate(command, ResolverUtil.resolveElementsInGroup(gs, md));



More information about the teiid-commits mailing list