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);