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$
+ }
}