Author: shawkins
Date: 2012-09-25 14:19:53 -0400 (Tue, 25 Sep 2012)
New Revision: 4469
Modified:
trunk/engine/src/main/java/org/teiid/query/optimizer/TriggerActionPlanner.java
trunk/engine/src/main/java/org/teiid/query/processor/proc/ExecDynamicSqlInstruction.java
trunk/engine/src/main/java/org/teiid/query/processor/proc/LoopInstruction.java
trunk/engine/src/main/java/org/teiid/query/resolver/command/InsertResolver.java
trunk/engine/src/main/java/org/teiid/query/resolver/command/UpdateResolver.java
trunk/engine/src/main/java/org/teiid/query/sql/proc/CreateProcedureCommand.java
trunk/engine/src/test/java/org/teiid/query/processor/TestTriggerActions.java
Log:
TEIID-2222 fix for npe with dyanmic sql in trigger
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/TriggerActionPlanner.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/optimizer/TriggerActionPlanner.java 2012-09-25
13:13:39 UTC (rev 4468)
+++
trunk/engine/src/main/java/org/teiid/query/optimizer/TriggerActionPlanner.java 2012-09-25
18:19:53 UTC (rev 4469)
@@ -97,7 +97,10 @@
ProcessorPlan queryPlan = QueryOptimizer.optimizePlan(query, metadata, idGenerator,
capFinder, analysisRecord, context);
result.setQueryPlan(queryPlan);
result.setLookupMap(RelationalNode.createLookupMap(query.getProjectedSymbols()));
- ProcedurePlan rowProcedure = (ProcedurePlan)QueryOptimizer.optimizePlan(new
CreateProcedureCommand(ta.getBlock()), metadata, idGenerator, capFinder, analysisRecord,
context);
+ CreateProcedureCommand command = new CreateProcedureCommand(ta.getBlock());
+ command.setVirtualGroup(ta.getView());
+ command.setUpdateType(userCommand.getClass().getSimpleName());
+ ProcedurePlan rowProcedure = (ProcedurePlan)QueryOptimizer.optimizePlan(command,
metadata, idGenerator, capFinder, analysisRecord, context);
result.setRowProcedure(rowProcedure);
return result;
}
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 2012-09-25
13:13:39 UTC (rev 4468)
+++
trunk/engine/src/main/java/org/teiid/query/processor/proc/ExecDynamicSqlInstruction.java 2012-09-25
18:19:53 UTC (rev 4469)
@@ -255,7 +255,11 @@
localContext.getFlattenedContextMap(variableMap);
Map<ElementSymbol, Expression> nameValueMap = new HashMap<ElementSymbol,
Expression>(variableMap.size());
for (Map.Entry<ElementSymbol, Object> entry : variableMap.entrySet()) {
- nameValueMap.put(entry.getKey(), new Constant(entry.getValue(),
entry.getKey().getType()));
+ if (entry.getValue() instanceof Expression) {
+ nameValueMap.put(entry.getKey(), (Expression) entry.getValue());
+ } else {
+ nameValueMap.put(entry.getKey(), new Constant(entry.getValue(),
entry.getKey().getType()));
+ }
}
return nameValueMap;
}
@@ -312,7 +316,11 @@
// do a recursion check
// Add group to recursion stack
CommandContext context = procEnv.getContext();
- context.pushCall(parentProcCommand.getVirtualGroup().getName());
+ if (parentProcCommand.getUpdateType() != null) {
+ context.pushCall(parentProcCommand.getUpdateType() + " " +
parentProcCommand.getVirtualGroup()); //$NON-NLS-1$
+ } else {
+ context.pushCall(parentProcCommand.getVirtualGroup().toString());
+ }
}
/**
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 2012-09-25
13:13:39 UTC (rev 4468)
+++
trunk/engine/src/main/java/org/teiid/query/processor/proc/LoopInstruction.java 2012-09-25
18:19:53 UTC (rev 4469)
@@ -73,7 +73,9 @@
elements = new ArrayList<ElementSymbol>(schema.size());
for(int i=0; i< schema.size(); i++){
Expression element = (Expression)schema.get(i);
- elements.add(new ElementSymbol(rsName + "." +
Symbol.getShortName(element))); //$NON-NLS-1$
+ ElementSymbol e = new ElementSymbol(rsName + Symbol.SEPARATOR +
Symbol.getShortName(element));
+ e.setType(element.getType());
+ elements.add(e);
}
}
for(int i=0; i< elements.size(); i++){
@@ -86,7 +88,7 @@
*/
public LoopInstruction clone(){
ProcessorPlan clonedPlan = this.plan.clone();
- return new LoopInstruction((Program)this.loopProgram.clone(), this.rsName,
clonedPlan, label);
+ return new LoopInstruction(this.loopProgram.clone(), this.rsName, clonedPlan,
label);
}
public String toString() {
Modified: trunk/engine/src/main/java/org/teiid/query/resolver/command/InsertResolver.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/resolver/command/InsertResolver.java 2012-09-25
13:13:39 UTC (rev 4468)
+++
trunk/engine/src/main/java/org/teiid/query/resolver/command/InsertResolver.java 2012-09-25
18:19:53 UTC (rev 4469)
@@ -254,12 +254,13 @@
valIter = insert.getValues().iterator();
}
while (varIter.hasNext()) {
- ElementSymbol varSymbol = varIter.next().clone();
-
+ ElementSymbol next = varIter.next();
+ ElementSymbol varSymbol = next.clone();
varSymbol.getGroupSymbol().setName(ProcedureReservedWords.CHANGING);
+ varSymbol.setType(DataTypeManager.DefaultDataClasses.BOOLEAN);
result.put(varSymbol, new Constant(Boolean.TRUE));
if (!changingOnly) {
- varSymbol = varSymbol.clone();
+ varSymbol = next.clone();
varSymbol.getGroupSymbol().setName(SQLConstants.Reserved.NEW);
result.put(varSymbol, (Expression)valIter.next());
}
@@ -271,13 +272,14 @@
Iterator<ElementSymbol> defaultIter = insertElmnts.iterator();
while(defaultIter.hasNext()) {
- ElementSymbol varSymbol = defaultIter.next().clone();
+ ElementSymbol next = varIter.next();
+ ElementSymbol varSymbol = next.clone();
varSymbol.getGroupSymbol().setName(ProcedureReservedWords.CHANGING);
+ varSymbol.setType(DataTypeManager.DefaultDataClasses.BOOLEAN);
result.put(varSymbol, new Constant(Boolean.FALSE));
-
if (!changingOnly) {
Expression value = ResolverUtil.getDefault(varSymbol, metadata);
- varSymbol = varSymbol.clone();
+ varSymbol = next.clone();
varSymbol.getGroupSymbol().setName(SQLConstants.Reserved.NEW);
result.put(varSymbol, value);
}
Modified: trunk/engine/src/main/java/org/teiid/query/resolver/command/UpdateResolver.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/resolver/command/UpdateResolver.java 2012-09-25
13:13:39 UTC (rev 4468)
+++
trunk/engine/src/main/java/org/teiid/query/resolver/command/UpdateResolver.java 2012-09-25
18:19:53 UTC (rev 4469)
@@ -33,6 +33,7 @@
import org.teiid.api.exception.query.QueryMetadataException;
import org.teiid.api.exception.query.QueryResolverException;
import org.teiid.core.TeiidComponentException;
+import org.teiid.core.types.DataTypeManager;
import org.teiid.language.SQLConstants;
import org.teiid.query.metadata.QueryMetadataInterface;
import org.teiid.query.metadata.TempMetadataAdapter;
@@ -103,9 +104,10 @@
for (Entry<ElementSymbol, Expression> entry : changing.entrySet()) {
ElementSymbol leftSymbol = entry.getKey().clone();
leftSymbol.getGroupSymbol().setName(ProcedureReservedWords.CHANGING);
+ leftSymbol.setType(DataTypeManager.DefaultDataClasses.BOOLEAN);
result.put(leftSymbol, new Constant(Boolean.TRUE));
if (!changingOnly) {
- leftSymbol = leftSymbol.clone();
+ leftSymbol = entry.getKey().clone();
leftSymbol.getGroupSymbol().setName(SQLConstants.Reserved.NEW);
result.put(leftSymbol, entry.getValue());
}
@@ -119,6 +121,7 @@
while(defaultIter.hasNext()) {
ElementSymbol varSymbol = defaultIter.next().clone();
varSymbol.getGroupSymbol().setName(ProcedureReservedWords.CHANGING);
+ varSymbol.setType(DataTypeManager.DefaultDataClasses.BOOLEAN);
result.put(varSymbol, new Constant(Boolean.FALSE));
}
Modified: trunk/engine/src/main/java/org/teiid/query/sql/proc/CreateProcedureCommand.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/sql/proc/CreateProcedureCommand.java 2012-09-25
13:13:39 UTC (rev 4468)
+++
trunk/engine/src/main/java/org/teiid/query/sql/proc/CreateProcedureCommand.java 2012-09-25
18:19:53 UTC (rev 4469)
@@ -54,6 +54,8 @@
private GroupSymbol virtualGroup;
+ private String updateType;
+
/**
* Constructor for CreateUpdateProcedureCommand.
*/
@@ -138,6 +140,7 @@
if (this.virtualGroup != null) {
copy.virtualGroup = this.virtualGroup.clone();
}
+ copy.updateType = this.updateType;
this.copyMetadataState(copy);
return copy;
}
@@ -234,4 +237,12 @@
this.virtualGroup = virtualGroup;
}
+ public void setUpdateType(String updateType) {
+ this.updateType = updateType;
+ }
+
+ public String getUpdateType() {
+ return updateType;
+ }
+
} // END CLASS
Modified: trunk/engine/src/test/java/org/teiid/query/processor/TestTriggerActions.java
===================================================================
---
trunk/engine/src/test/java/org/teiid/query/processor/TestTriggerActions.java 2012-09-25
13:13:39 UTC (rev 4468)
+++
trunk/engine/src/test/java/org/teiid/query/processor/TestTriggerActions.java 2012-09-25
18:19:53 UTC (rev 4469)
@@ -29,6 +29,7 @@
import java.util.List;
import org.junit.Test;
+import org.teiid.api.exception.query.QueryProcessingException;
import org.teiid.metadata.Table;
import org.teiid.query.metadata.TransformationMetadata;
import org.teiid.query.optimizer.TestOptimizer;
@@ -60,7 +61,7 @@
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)};
+ List<?>[] expected = new List[] {Arrays.asList(1)};
helpProcess(plan, context, dm, expected);
}
@@ -79,10 +80,52 @@
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(6)};
+ List<?>[] expected = new List[] {Arrays.asList(6)};
helpProcess(plan, context, dm, expected);
}
+ @Test public void testDynamic() 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("FOR EACH ROW BEGIN ATOMIC END");
+ t.setUpdatePlan("");
+ t.setInsertPlan("FOR EACH ROW BEGIN execute immediate 'delete from gx where
gx.x = new.x'; END");
+
+ String sql = "insert into gx (x, y) select e1, e2 from pm1.g1";
+
+ 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(6)};
+ helpProcess(plan, context, dm, expected);
+ }
+
+ @Test public void testDynamicRecursion() throws Exception {
+ TransformationMetadata metadata = TestUpdateValidator.example1();
+ TestUpdateValidator.createView("select 'a' as x, 2 as y", metadata,
GX);
+ Table t = metadata.getMetadataStore().getSchemas().get(VM1).getTables().get(GX);
+ t.setDeletePlan("FOR EACH ROW BEGIN ATOMIC insert into gx (x, y) values (old.x,
old.y); END");
+ t.setUpdatePlan("");
+ t.setInsertPlan("FOR EACH ROW BEGIN execute immediate 'delete from gx where
gx.x = new.x'; END");
+
+ String sql = "insert into gx (x, y) select e1, e2 from pm1.g1";
+
+ 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);
+ try {
+ helpProcess(plan, context, dm, null);
+ fail();
+ } catch (QueryProcessingException e) {
+ assertEquals("TEIID30168 Couldn't execute the dynamic SQL command
\"EXECUTE IMMEDIATE 'delete from gx where gx.x = new.x'\" with the SQL
statement \"'delete from gx where gx.x = new.x'\" due to: TEIID30347
There is a recursive invocation of group 'Insert gx'. Please correct the
SQL.", e.getMessage());
+ }
+ }
+
@Test public void testDelete() throws Exception {
TransformationMetadata metadata = TestUpdateValidator.example1();
TestUpdateValidator.createView("select 1 as x, 2 as y", metadata, GX);
@@ -99,7 +142,7 @@
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)};
+ List<?>[] expected = new List[] {Arrays.asList(1)};
helpProcess(plan, context, dm, expected);
}
@@ -119,7 +162,7 @@
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)};
+ 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));
}
@@ -161,7 +204,7 @@
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)};
+ 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));
}