Author: shawkins
Date: 2009-07-14 13:38:11 -0400 (Tue, 14 Jul 2009)
New Revision: 1127
Modified:
trunk/engine/src/main/java/com/metamatrix/query/sql/visitor/CriteriaTranslatorVisitor.java
trunk/engine/src/main/java/com/metamatrix/query/validator/ValidationVisitor.java
trunk/engine/src/main/resources/com/metamatrix/query/i18n.properties
trunk/engine/src/test/java/com/metamatrix/query/validator/TestValidator.java
Log:
TEIID-720 fixing validation logic for translate criteria.
Modified:
trunk/engine/src/main/java/com/metamatrix/query/sql/visitor/CriteriaTranslatorVisitor.java
===================================================================
---
trunk/engine/src/main/java/com/metamatrix/query/sql/visitor/CriteriaTranslatorVisitor.java 2009-07-14
16:31:11 UTC (rev 1126)
+++
trunk/engine/src/main/java/com/metamatrix/query/sql/visitor/CriteriaTranslatorVisitor.java 2009-07-14
17:38:11 UTC (rev 1127)
@@ -22,13 +22,26 @@
package com.metamatrix.query.sql.visitor;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
import com.metamatrix.core.util.Assertion;
-import com.metamatrix.query.sql.LanguageVisitor;
-import com.metamatrix.query.sql.lang.*;
-import com.metamatrix.query.sql.symbol.*;
-import com.metamatrix.query.sql.proc.*;
+import com.metamatrix.query.sql.lang.BetweenCriteria;
+import com.metamatrix.query.sql.lang.CompareCriteria;
+import com.metamatrix.query.sql.lang.CompoundCriteria;
+import com.metamatrix.query.sql.lang.Criteria;
+import com.metamatrix.query.sql.lang.DependentSetCriteria;
+import com.metamatrix.query.sql.lang.IsNullCriteria;
+import com.metamatrix.query.sql.lang.MatchCriteria;
+import com.metamatrix.query.sql.lang.SetCriteria;
+import com.metamatrix.query.sql.proc.CriteriaSelector;
+import com.metamatrix.query.sql.symbol.ElementSymbol;
+import com.metamatrix.query.sql.symbol.Expression;
+import com.metamatrix.query.sql.symbol.Reference;
/**
* <p> This class is used to translate criteria specified on the user's update
command against
@@ -37,11 +50,8 @@
* if a CriteriaSelector is specified, also if the user explicty defines translations for
some
* of the elements those translations override any symbol mappings.</p>
*/
-public class CriteriaTranslatorVisitor extends LanguageVisitor {
+public class CriteriaTranslatorVisitor extends ExpressionMappingVisitor {
- // map between virtual elements and the elements in its query transformation
- private Map symbolMap;
-
// criteria selector specified on the TranslateCriteria obj
private CriteriaSelector selector;
@@ -49,13 +59,15 @@
private Collection translations;
// list of translated criteria
- private List translatedCriteria;
+ private List<Criteria> translatedCriteria = new ArrayList<Criteria>();
+
+ private Map<Reference, Reference> impliedParameters = new HashMap<Reference,
Reference>();
/**
* <p> This constructor initialises the visitor</p>
*/
public CriteriaTranslatorVisitor() {
- this.translatedCriteria = new ArrayList();
+ this(null);
}
/**
@@ -64,31 +76,10 @@
* defining the virtual group
*/
public CriteriaTranslatorVisitor(Map symbolMap) {
- this();
+ super(symbolMap);
Assertion.isNotNull(symbolMap);
- this.symbolMap = symbolMap;
}
- /**
- * <p>Get the symbol map between virtual group elements and the expressions
that define
- * them on the query transform of the virtual group.</p>
- * @param symbolMap A map of virtual elements to their counterparts in transform
- * defining the virtual group
- */
- protected Symbol getMappedSymbol(Symbol symbol) {
- return (Symbol) this.symbolMap.get(symbol);
- }
-
- /**
- * <p>Set the symbol map between virtual group elements and the expressions
that define
- * them on the query transform of the virtual group.</p>
- * @param symbolMap A map of virtual elements to their counterparts in transform
- * defining the virtual group
- */
- public void setSymbolMap(Map symbolMap) {
- this.symbolMap = symbolMap;
- }
-
/**
* <p>Set the criteria selector used to restrict the part of the criteria that
needs to be
* translated.</p>
@@ -121,34 +112,9 @@
if (!selectorContainsCriteriaElements(obj, CriteriaSelector.BETWEEN)) {
return;
}
-
- obj.setExpression(replaceExpression(obj.getExpression()));
- obj.setLowerExpression(replaceExpression(obj.getLowerExpression()));
- obj.setUpperExpression(replaceExpression(obj.getUpperExpression()));
-
+ super.visit(obj);
translatedCriteria.add(obj);
}
-
- /**
- * <p> This method updates the <code>CaseExpression</code> object
it receives as an
- * argument by replacing the virtual elements present in the expressions in the
- * function with translated expressions.</p>
- * @param obj The CaseExpression object to be updated with translated expressions
- */
- public void visit(CaseExpression obj) {
- obj.setExpression(replaceExpression(obj.getExpression()));
- int whenCount = obj.getWhenCount();
- ArrayList whens = new ArrayList(whenCount);
- ArrayList thens = new ArrayList(whenCount);
- for(int i = 0; i < whenCount; i++) {
- whens.add(replaceExpression(obj.getWhenExpression(i)));
- thens.add(replaceExpression(obj.getThenExpression(i)));
- }
- obj.setWhen(whens, thens);
- if (obj.getElseExpression() != null) {
- obj.setElseExpression(replaceExpression(obj.getElseExpression()));
- }
- }
/**
* <p> This method updates the <code>CompareCriteria</code> object
it receives as an
@@ -162,9 +128,7 @@
return;
}
- obj.setLeftExpression(replaceExpression(obj.getLeftExpression()));
- obj.setRightExpression(replaceExpression(obj.getRightExpression()));
-
+ super.visit(obj);
translatedCriteria.add(obj);
}
@@ -179,8 +143,7 @@
if (!selectorContainsCriteriaElements(obj, CriteriaSelector.IS_NULL)) {
return;
}
- obj.setExpression(replaceExpression(obj.getExpression()));
-
+ super.visit(obj);
translatedCriteria.add(obj);
}
@@ -196,29 +159,9 @@
return;
}
- obj.setLeftExpression(replaceExpression(obj.getLeftExpression()));
- obj.setRightExpression(replaceExpression(obj.getRightExpression()));
-
+ super.visit(obj);
translatedCriteria.add(obj);
}
-
- /**
- * <p> This method updates the <code>SearchedCaseExpression</code>
object it receives as an
- * argument by replacing the virtual elements present in the expressions in the
- * function with translated expressions.</p>
- * @param obj The SearchedCaseExpression object to be updated with translated
expressions
- */
- public void visit(SearchedCaseExpression obj) {
- int whenCount = obj.getWhenCount();
- ArrayList thens = new ArrayList(whenCount);
- for(int i = 0; i < whenCount; i++) {
- thens.add(replaceExpression(obj.getThenExpression(i)));
- }
- obj.setWhen(obj.getWhen(), thens);
- if (obj.getElseExpression() != null) {
- obj.setElseExpression(replaceExpression(obj.getElseExpression()));
- }
- }
/**
* <p> This method updates the <code>SetCriteria</code> object it
receives as an
@@ -232,19 +175,7 @@
return;
}
- obj.setExpression(replaceExpression(obj.getExpression()));
-
- // create a new list containing physical elements and constants
- List valuesList = new ArrayList(obj.getNumberOfValues());
-
- // iterate over the list containing virtual elements/constants
- Iterator valuesIter = obj.getValues().iterator();
- while(valuesIter.hasNext()) {
- Expression valueExpr = (Expression) valuesIter.next();
- valuesList.add(replaceExpression(valueExpr));
- }
- obj.setValues(valuesList);
-
+ super.visit(obj);
translatedCriteria.add(obj);
}
@@ -260,28 +191,10 @@
return;
}
- obj.setExpression(replaceExpression(obj.getExpression()));
-
+ super.visit(obj);
translatedCriteria.add(obj);
}
- /**
- * <p> This method updates the <code>Function</code> object it
receives as an
- * argument by replacing the virtual elements present in the expressions in the
- * function with translated expressions</p>
- * @param obj The Function object to be updated with translated expressions
- */
- public void visit(Function obj) {
-
- int argLength = obj.getArgs().length;
- Expression args[] = new Expression [argLength];
-
- for(int i=0; i < argLength; i++) {
- args[i] = replaceExpression(obj.getArg(i));
- }
- obj.setArgs(args);
- }
-
/* ############### Helper Methods ################## */
private boolean selectorContainsCriteriaElements(Criteria criteria, int criteriaType)
{
@@ -302,44 +215,9 @@
return true;
}
- /**
- * Utility method that implements a common pattern used throughout this class.
- * @param exp an expression
- * @return the translated expression, if the the expression needs to the
- * translated. Otherwise, the same expression.
- */
- private Expression replaceExpression(Expression exp) {
- if(exp instanceof AliasSymbol) {
- exp = ((AliasSymbol)exp).getSymbol();
- }
- if(exp instanceof ElementSymbol) {
- exp = getTranslatedExpression((ElementSymbol)exp);
- }
- return exp;
- }
-
- /**
- * <p> This method looks up the symbol map between
<code>ElementSymbol</code>s at the virtual
- * group level to the <code>Expression</code>s they map to in the query
transformation
- * that defines the virtual group, if there is valid translation expresion in the map
the
- * translated expression is returned else a the element symbol is
- * returned back as there is no mapping (physical elements).</p>
- * @param obj The virtual <code>ElementSymbol</code> object whose
counterpart used in
- * the query transformation of the virtual group is returned
- * @return An <code>Expression</code> object or the elementSymbol if the
- * object could not be mapped
- */
- private Expression getMappedExpression(ElementSymbol obj) {
-
- Expression expr = (Expression) this.symbolMap.get(obj);
- if(expr != null) {
- return expr;
- }
- return obj;
- }
-
- private Expression getTranslatedExpression(ElementSymbol obj) {
- if(this.translations != null) {
+ @Override
+ public Expression replaceExpression(Expression obj) {
+ if (this.translations != null && obj instanceof ElementSymbol) {
Iterator transIter = this.translations.iterator();
while(transIter.hasNext()) {
CompareCriteria compCrit = (CompareCriteria) transIter.next();
@@ -350,9 +228,8 @@
return compCrit.getRightExpression();
}
}
- }
-
- return getMappedExpression(obj);
+ }
+ return super.replaceExpression(obj);
}
/**
Modified:
trunk/engine/src/main/java/com/metamatrix/query/validator/ValidationVisitor.java
===================================================================
---
trunk/engine/src/main/java/com/metamatrix/query/validator/ValidationVisitor.java 2009-07-14
16:31:11 UTC (rev 1126)
+++
trunk/engine/src/main/java/com/metamatrix/query/validator/ValidationVisitor.java 2009-07-14
17:38:11 UTC (rev 1127)
@@ -511,30 +511,34 @@
Collection groups = GroupCollectorVisitor.getGroups(this.currentCommand, true);
int selectType = obj.getSelector().getSelectorType();
- Iterator critIter = PredicateCollectorVisitor.getPredicates(userCrit).iterator();
+ Collection predicates = PredicateCollectorVisitor.getPredicates(userCrit);
+ if (predicates.size() != Criteria.separateCriteriaByAnd(userCrit).size()) {
+ handleValidationError(QueryPlugin.Util.getString("ValidationVisitor.translated_or"),
userCrit); //$NON-NLS-1$
+ }
+ Iterator critIter = predicates.iterator();
while(critIter.hasNext()) {
Criteria predCrit = (Criteria) critIter.next();
if(selectType != CriteriaSelector.NO_TYPE) {
if(predCrit instanceof CompareCriteria) {
CompareCriteria ccCrit = (CompareCriteria) predCrit;
if(selectType != ccCrit.getOperator()) {
- return;
+ continue;
}
} else if(predCrit instanceof MatchCriteria) {
if(selectType != CriteriaSelector.LIKE) {
- return;
+ continue;
}
} else if(predCrit instanceof IsNullCriteria) {
if(selectType != CriteriaSelector.IS_NULL) {
- return;
+ continue;
}
} else if(predCrit instanceof SetCriteria) {
if(selectType != CriteriaSelector.IN) {
- return;
+ continue;
}
} else if(predCrit instanceof BetweenCriteria) {
if(selectType != CriteriaSelector.BETWEEN) {
- return;
+ continue;
}
}
}
Modified: trunk/engine/src/main/resources/com/metamatrix/query/i18n.properties
===================================================================
--- trunk/engine/src/main/resources/com/metamatrix/query/i18n.properties 2009-07-14
16:31:11 UTC (rev 1126)
+++ trunk/engine/src/main/resources/com/metamatrix/query/i18n.properties 2009-07-14
17:38:11 UTC (rev 1127)
@@ -280,6 +280,7 @@
ERR.015.012.0027 = Expressions of type OBJECT, CLOB, BLOB, or XML cannot be used in
comparison: {0}.
ValidationVisitor.invalid_lookup_key=Expressions of type OBJECT, CLOB, BLOB, or XML
cannot be used as LOOKUP key columns: {0}.
ValidationVisitor.limit_not_valid_for_xml=The limit clause cannot be used on an XML
document query.
+ValidationVisitor.translated_or=Translated user criteria must not contain OR criteria
ValidateCriteriaVistitor.element_not_comparable = The following data elements are not
supported in comparison criteria: {0}.
ERR.015.012.0028 = The following data elements are not supported in match criteria: {0}.
ERR.015.012.0029 = INSERT, UPDATE, and DELETE not allowed on XML documents
Modified: trunk/engine/src/test/java/com/metamatrix/query/validator/TestValidator.java
===================================================================
---
trunk/engine/src/test/java/com/metamatrix/query/validator/TestValidator.java 2009-07-14
16:31:11 UTC (rev 1126)
+++
trunk/engine/src/test/java/com/metamatrix/query/validator/TestValidator.java 2009-07-14
17:38:11 UTC (rev 1127)
@@ -1281,6 +1281,23 @@
helpFailProcedure(procedure, userQuery,
FakeMetadataObject.Props.UPDATE_PROCEDURE);
}
+
+ // virtual group elements used in procedure in if statement(TRANSLATE CRITERIA)
+ // failure, aggregate function in query transform
+ public void testCreateUpdateProcedure18a() {
+ String procedure = "CREATE PROCEDURE "; //$NON-NLS-1$
+ procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
+ procedure = procedure + "DECLARE integer var1;\n"; //$NON-NLS-1$
+ procedure = procedure + "Select pm1.g1.e2 from pm1.g1 where TRANSLATE =
CRITERIA ON (e3);\n"; //$NON-NLS-1$
+ procedure = procedure + "ROWS_UPDATED =0;\n"; //$NON-NLS-1$
+ procedure = procedure + "END\n"; //$NON-NLS-1$
+
+ String userQuery = "UPDATE vm1.g3 SET x='x' where y like
'%a' and e3= 1"; //$NON-NLS-1$
+
+ helpFailProcedure(procedure, userQuery,
+ FakeMetadataObject.Props.UPDATE_PROCEDURE);
+ }
+
// virtual group elements used in procedure in if statement(TRANSLATE CRITERIA)
// failure, translated criteria elements not present on groups of command
@@ -1387,7 +1404,21 @@
helpValidateProcedure(procedure, userQuery,
FakeMetadataObject.Props.UPDATE_PROCEDURE);
}
+
+ public void testCreateUpdateProcedure28() {
+ String procedure = "CREATE PROCEDURE "; //$NON-NLS-1$
+ procedure = procedure + "BEGIN\n"; //$NON-NLS-1$
+ procedure = procedure + "DECLARE integer var1;\n"; //$NON-NLS-1$
+ procedure = procedure + "Select pm1.g2.e2 from pm1.g2 where TRANSLATE
CRITERIA;\n"; //$NON-NLS-1$
+ procedure = procedure + "ROWS_UPDATED =0;\n"; //$NON-NLS-1$
+ procedure = procedure + "END\n"; //$NON-NLS-1$
+ String userQuery = "UPDATE vm1.g3 SET x='x' where y = 1 or y =
2"; //$NON-NLS-1$
+
+ helpFailProcedure(procedure, userQuery,
+ FakeMetadataObject.Props.UPDATE_PROCEDURE);
+ }
+
// using aggregate function within a procedure - defect #8394
public void testCreateUpdateProcedure31() {
String procedure = "CREATE PROCEDURE "; //$NON-NLS-1$