[teiid-commits] teiid SVN: r3678 - in branches/7.6.x: engine/src/main/java/org/teiid/query/optimizer/relational and 3 other directories.

teiid-commits at lists.jboss.org teiid-commits at lists.jboss.org
Mon Nov 21 15:41:44 EST 2011


Author: shawkins
Date: 2011-11-21 15:41:44 -0500 (Mon, 21 Nov 2011)
New Revision: 3678

Modified:
   branches/7.6.x/build/kits/jboss-container/teiid-releasenotes.html
   branches/7.6.x/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java
   branches/7.6.x/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
   branches/7.6.x/engine/src/main/resources/org/teiid/query/i18n.properties
   branches/7.6.x/engine/src/test/java/org/teiid/query/processor/TestProcessor.java
   branches/7.6.x/engine/src/test/java/org/teiid/query/processor/TestTriggerActions.java
Log:
TEIID-1843 fix for stackoverflow

Modified: branches/7.6.x/build/kits/jboss-container/teiid-releasenotes.html
===================================================================
--- branches/7.6.x/build/kits/jboss-container/teiid-releasenotes.html	2011-11-21 16:58:13 UTC (rev 3677)
+++ branches/7.6.x/build/kits/jboss-container/teiid-releasenotes.html	2011-11-21 20:41:44 UTC (rev 3678)
@@ -50,7 +50,7 @@
 
 <h2><a name="Compatibility">Compatibility Issues</a></h2>
 <ul>
-  <li>TRANSLATE/HAS CRITERIA has been deprecated.  An alternative approach to update procedures will be introduced in a subsequent version.
+  <li>TRANSLATE/HAS CRITERIA has been deprecated.  INSTEAD OF trigger actions should be used instead.
   <li>Support for named parameter syntax using param=value has been deprecated, since it is ambiguous with a comparison predicate boolean value expression.  param<b>=></b>value should be used instead.  
   <li>Support for using the FROM clause post item hints MAKEDEP/MAKENOTDEP has been deprecated.  Use the pre item comment hint syntax instead, e.g. /*+ MAKEDEP */ tbl
 </ul>

Modified: branches/7.6.x/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java
===================================================================
--- branches/7.6.x/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java	2011-11-21 16:58:13 UTC (rev 3677)
+++ branches/7.6.x/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java	2011-11-21 20:41:44 UTC (rev 3678)
@@ -159,6 +159,11 @@
 	private PlanHints hints = new PlanHints();
 	private Option option;
 	private SourceHint sourceHint;
+	private static ThreadLocal<Boolean> planningLoop = new ThreadLocal<Boolean>() {
+		protected Boolean initialValue() {
+			return Boolean.FALSE;
+		}
+	};
 	
     public ProcessorPlan optimize(
         Command command)
@@ -314,18 +319,23 @@
                 CorrelatedReferenceCollectorVisitor.collectReferences(subCommand, localGroupSymbols, correlatedReferences);
                 ProcessorPlan procPlan = QueryOptimizer.optimizePlan(subCommand, metadata, idGenerator, capFinder, analysisRecord, context);
                 container.getCommand().setProcessorPlan(procPlan);
-                if (!correlatedReferences.isEmpty()) {
-	                SymbolMap map = new SymbolMap();
-	                for (Reference reference : correlatedReferences) {
-	    				map.addMapping(reference.getExpression(), reference.getExpression());
-	    			}
-	                container.getCommand().setCorrelatedReferences(map);
-                }
+                setCorrelatedReferences(container, correlatedReferences);
             }
             node.addGroups(GroupsUsedByElementsVisitor.getGroups(node.getCorrelatedReferenceElements()));
         }
     }
 
+	private void setCorrelatedReferences(SubqueryContainer<?> container,
+			List<Reference> correlatedReferences) {
+		if (!correlatedReferences.isEmpty()) {
+		    SymbolMap map = new SymbolMap();
+		    for (Reference reference : correlatedReferences) {
+				map.addMapping(reference.getExpression(), reference.getExpression());
+			}
+		    container.getCommand().setCorrelatedReferences(map);
+		}
+	}
+
 	private static Set<GroupSymbol> getGroupSymbols(PlanNode plan) {
 		Set<GroupSymbol> groupSymbols = new HashSet<GroupSymbol>();
         for (PlanNode source : NodeEditor.findAllNodes(plan, NodeConstants.Types.SOURCE)) {
@@ -588,6 +598,14 @@
 				context.accessedPlanningObject(sp.getProcedureID());
 			}
 		}
+		for (SubqueryContainer<?> subqueryContainer : ValueIteratorProviderCollectorVisitor.getValueIteratorProviders(container)) {
+			if (subqueryContainer.getCommand().getCorrelatedReferences() != null) {
+				continue;
+			}
+			List<Reference> correlatedReferences = new ArrayList<Reference>();
+			CorrelatedReferenceCollectorVisitor.collectReferences(subqueryContainer.getCommand(), Arrays.asList(container.getGroup()), correlatedReferences);
+			setCorrelatedReferences(subqueryContainer, correlatedReferences);
+		}
 		String cacheString = "transformation/" + container.getClass().getSimpleName().toUpperCase(); //$NON-NLS-1$
 		Command c = (Command)metadata.getFromMetadataCache(metadataId, cacheString);
 		if (c == null) {
@@ -637,13 +655,22 @@
 				throw new QueryPlannerException(QueryPlugin.Util.getString("RelationalPlanner.nonpushdown_command", container)); //$NON-NLS-1$
 			}
 			
-			//treat this as an update procedure
-			if (container instanceof Update) {
-				c = QueryRewriter.createUpdateProcedure((Update)container, metadata, context);
-			} else {
-				c = QueryRewriter.createDeleteProcedure((Delete)container, metadata, context);
+			try {
+				if (planningLoop.get()) {
+					throw new QueryPlannerException(QueryPlugin.Util.getString("RelationalPlanner.nonpushdown_expression", container)); //$NON-NLS-1$
+				}
+				planningLoop.set(Boolean.TRUE);
+				
+				//treat this as an update procedure
+				if (container instanceof Update) {
+					c = QueryRewriter.createUpdateProcedure((Update)container, metadata, context);
+				} else {
+					c = QueryRewriter.createDeleteProcedure((Delete)container, metadata, context);
+				}
+				addNestedCommand(sourceNode, container.getGroup(), container, c, false);
+			} finally {
+				planningLoop.set(Boolean.FALSE);
 			}
-			addNestedCommand(sourceNode, container.getGroup(), container, c, false);
 			return false;
 		}
 		

Modified: branches/7.6.x/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
===================================================================
--- branches/7.6.x/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java	2011-11-21 16:58:13 UTC (rev 3677)
+++ branches/7.6.x/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java	2011-11-21 20:41:44 UTC (rev 3678)
@@ -1060,7 +1060,7 @@
         } else if (criteria instanceof DependentSetCriteria) {
             criteria = rewriteDependentSetCriteria((DependentSetCriteria)criteria);
         } else if (criteria instanceof ExpressionCriteria) {
-        	return new CompareCriteria(((ExpressionCriteria) criteria).getExpression(), CompareCriteria.EQ, new Constant(Boolean.TRUE));
+        	return rewriteCriteria(new CompareCriteria(((ExpressionCriteria) criteria).getExpression(), CompareCriteria.EQ, new Constant(Boolean.TRUE)));
         }
     	
         return evaluateCriteria(criteria);

Modified: branches/7.6.x/engine/src/main/resources/org/teiid/query/i18n.properties
===================================================================
--- branches/7.6.x/engine/src/main/resources/org/teiid/query/i18n.properties	2011-11-21 16:58:13 UTC (rev 3677)
+++ branches/7.6.x/engine/src/main/resources/org/teiid/query/i18n.properties	2011-11-21 20:41:44 UTC (rev 3678)
@@ -924,6 +924,7 @@
 connection_factory_not_found=Failed to find the Connection Factory with JNDI name {0}. Please check the name or deploy the Connection Factory with specified name.
 
 RelationalPlanner.nonpushdown_command=Source UPDATE or DELETE command "{0}" contains non-pushdown constructs and no compensating action can be taken as the table lacks a unique key or the source does not support equality predicates. 
+RelationalPlanner.nonpushdown_expression=Source UPDATE or DELETE command "{0}" contains non-pushdown constructs that cannot be simplified into a compensating action.
 
 Translate.error=Cannot translate criteria "{0}", it is not matched by selector "{1}"
 

Modified: branches/7.6.x/engine/src/test/java/org/teiid/query/processor/TestProcessor.java
===================================================================
--- branches/7.6.x/engine/src/test/java/org/teiid/query/processor/TestProcessor.java	2011-11-21 16:58:13 UTC (rev 3677)
+++ branches/7.6.x/engine/src/test/java/org/teiid/query/processor/TestProcessor.java	2011-11-21 20:41:44 UTC (rev 3678)
@@ -41,6 +41,7 @@
 import java.util.StringTokenizer;
 
 import org.junit.Test;
+import org.teiid.api.exception.query.QueryPlannerException;
 import org.teiid.client.metadata.ParameterInfo;
 import org.teiid.common.buffer.BlockedException;
 import org.teiid.common.buffer.BufferManager;
@@ -7573,6 +7574,17 @@
         helpProcess(plan, dataManager, expected);
     }
     
+    @Test(expected=QueryPlannerException.class) public void testUpdateCompensationNotPossible() throws Exception {
+    	String sql = "update pm1.g1 set e4 = (select e4 from pm1.g2 where pm1.g2.e2 = pm1.g1.e2) where e1 = 'a'"; //$NON-NLS-1$
+    	
+        FakeDataManager dataManager = new FakeDataManager();
+        sampleData1(dataManager);
+        
+        BasicSourceCapabilities caps = getTypicalCapabilities();
+        caps.setCapabilitySupport(Capability.QUERY_SUBQUERIES_SCALAR, false);
+        helpGetPlan(helpParse(sql), RealMetadataFactory.example4(), new DefaultCapabilitiesFinder(caps), createCommandContext());
+    }
+    
     @Test public void testDupSelect() throws Exception {
     	String sql = "select e1, e1 from pm1.g1";
         

Modified: branches/7.6.x/engine/src/test/java/org/teiid/query/processor/TestTriggerActions.java
===================================================================
--- branches/7.6.x/engine/src/test/java/org/teiid/query/processor/TestTriggerActions.java	2011-11-21 16:58:13 UTC (rev 3677)
+++ branches/7.6.x/engine/src/test/java/org/teiid/query/processor/TestTriggerActions.java	2011-11-21 20:41:44 UTC (rev 3678)
@@ -124,6 +124,27 @@
     	assertEquals("UPDATE pm1.g1 SET e2 = 5 WHERE e2 = 2", dm.getQueries().get(0));
 	}
 	
+	@Test public void testUpdateWithChanging() 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 = case when changing.y then new.y end where e2 = old.y; END");
+		t.setInsertPlan("");
+		
+		String sql = "update gx set y = 5";
+		
+		FakeDataManager dm = new FakeDataManager();
+		FakeDataStore.addTable("pm1.g1", dm, metadata);
+		
+		CommandContext context = createCommandContext();
+        BasicSourceCapabilities caps = TestOptimizer.getTypicalCapabilities();
+        ProcessorPlan plan = TestProcessor.helpGetPlan(TestResolver.helpResolve(sql, metadata), metadata, new DefaultCapabilitiesFinder(caps), context);
+        List<?>[] expected = new List[] {Arrays.asList(1)};
+    	helpProcess(plan, context, dm, expected);
+    	assertEquals("UPDATE pm1.g1 SET e2 = 5 WHERE e2 = 2", dm.getQueries().get(0));
+	}
+	
 	@Test public void testUpdateWithNonConstant() throws Exception {
 		TransformationMetadata metadata = TestUpdateValidator.example1();
 		TestUpdateValidator.createView("select 1 as x, 2 as y", metadata, GX);



More information about the teiid-commits mailing list