You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@chemistry.apache.org by fg...@apache.org on 2011/04/26 15:34:32 UTC
svn commit: r1096750 - in
/chemistry/opencmis/trunk/chemistry-opencmis-server:
chemistry-opencmis-server-inmemory/src/test/java/org/apache/chemistry/opencmis/inmemory/query/
chemistry-opencmis-server-support/src/main/antlr3/org/apache/chemistry/opencmi...
Author: fguillaume
Date: Tue Apr 26 13:34:32 2011
New Revision: 1096750
URL: http://svn.apache.org/viewvc?rev=1096750&view=rev
Log:
Make parser and AbstractPredicateWalker check type qualifiers for IN_TREE, IN_FOLDER, CONTAINS; more type verification in QueryObject
Modified:
chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/test/java/org/apache/chemistry/opencmis/inmemory/query/EvalQueryTest.java
chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/test/java/org/apache/chemistry/opencmis/inmemory/query/QueryTypesTest.java
chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-support/src/main/antlr3/org/apache/chemistry/opencmis/server/support/query/CmisQueryWalker.g
chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-support/src/main/java/org/apache/chemistry/opencmis/server/support/query/AbstractPredicateWalker.java
chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-support/src/main/java/org/apache/chemistry/opencmis/server/support/query/PredicateWalker.java
chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-support/src/main/java/org/apache/chemistry/opencmis/server/support/query/QueryObject.java
Modified: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/test/java/org/apache/chemistry/opencmis/inmemory/query/EvalQueryTest.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/test/java/org/apache/chemistry/opencmis/inmemory/query/EvalQueryTest.java?rev=1096750&r1=1096749&r2=1096750&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/test/java/org/apache/chemistry/opencmis/inmemory/query/EvalQueryTest.java (original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/test/java/org/apache/chemistry/opencmis/inmemory/query/EvalQueryTest.java Tue Apr 26 13:34:32 2011
@@ -603,7 +603,7 @@ public class EvalQueryTest extends Abstr
res = doQuery(statement);
fail("Unknown type in folder should throw exception");
} catch (Exception e) {
- assertTrue(e.toString().contains("must be in FROM list"));
+ assertTrue(e.toString().contains("is neither a type query name nor an alias"));
log.debug("expected Exception: " + e);
}
}
@@ -632,7 +632,7 @@ public class EvalQueryTest extends Abstr
res = doQuery(statement);
fail("Unknown type in folder should throw exception");
} catch (Exception e) {
- assertTrue(e.toString().contains("must be in FROM list"));
+ assertTrue(e.toString().contains("is neither a type query name nor an alias"));
log.debug("expected Exception: " + e);
}
}
Modified: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/test/java/org/apache/chemistry/opencmis/inmemory/query/QueryTypesTest.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/test/java/org/apache/chemistry/opencmis/inmemory/query/QueryTypesTest.java?rev=1096750&r1=1096749&r2=1096750&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/test/java/org/apache/chemistry/opencmis/inmemory/query/QueryTypesTest.java (original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/test/java/org/apache/chemistry/opencmis/inmemory/query/QueryTypesTest.java Tue Apr 26 13:34:32 2011
@@ -20,12 +20,15 @@ package org.apache.chemistry.opencmis.in
import static org.junit.Assert.*;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.antlr.runtime.RecognitionException;
+import org.antlr.runtime.tree.Tree;
import org.apache.chemistry.opencmis.commons.definitions.TypeDefinition;
import org.apache.chemistry.opencmis.inmemory.TypeManagerImpl;
+import org.apache.chemistry.opencmis.server.support.query.AbstractPredicateWalker;
import org.apache.chemistry.opencmis.server.support.query.CmisQueryWalker;
import org.apache.chemistry.opencmis.server.support.query.CmisSelector;
import org.apache.chemistry.opencmis.server.support.query.ColumnReference;
@@ -41,6 +44,16 @@ public class QueryTypesTest extends Abst
private static final Log LOG = LogFactory.getLog(QueryTypesTest.class);
private TypeManagerImpl tm;
+ private TestPredicateWalker pw;
+
+ public static class TestPredicateWalker extends AbstractPredicateWalker {
+ List<Integer> ids = new LinkedList<Integer>();
+ @Override
+ public Object walkId(Tree node) {
+ ids.add(node.getTokenStartIndex());
+ return null;
+ }
+ }
@Before
public void setUp() {
@@ -54,7 +67,9 @@ public class QueryTypesTest extends Abst
}
// initialize query object with type manager
- super.setUp(new QueryObject(tm), null);
+ // and test the abstract predicate walker
+ pw = new TestPredicateWalker();
+ super.setUp(new QueryObject(tm), pw);
}
@After
@@ -170,6 +185,37 @@ public class QueryTypesTest extends Abst
}
@Test
+ public void resolveTypesWithTwoFromsSameTypeCorrectlyQualified()
+ throws Exception {
+ String statement = "SELECT A.Title FROM BookType A JOIN BookType B";
+
+ CmisQueryWalker walker = traverseStatement(statement);
+ assertNotNull(walker);
+ Map<String, String> types = queryObj.getTypes();
+ assertEquals(2, types.size());
+ List<CmisSelector> selects = queryObj.getSelectReferences();
+ assertEquals(1, selects.size());
+ ColumnReference colRef = ((ColumnReference) selects.get(0));
+ assertEquals(bookType, colRef.getTypeDefinition());
+ assertEquals(TITLE_PROP, colRef.getPropertyQueryName());
+ assertEquals("A", colRef.getQualifier());
+ }
+
+ @Test
+ public void resolveTypesWithTwoFromsSameTypeAmbiguouslyQualified()
+ throws Exception {
+ String statement = "SELECT BookType.Title FROM BookType A JOIN BookType B";
+ try {
+ traverseStatement(statement);
+ fail("Select with an ambiguously qualified property should fail.");
+ } catch (Exception e) {
+ assertTrue(e instanceof RecognitionException);
+ assertTrue(e.toString().contains(
+ "BookType is an ambiguous type query name"));
+ }
+ }
+
+ @Test
public void resolveTypesWithTwoFromsUnqualified() throws Exception {
String statement = "SELECT Title, MyStringProp FROM BookType JOIN MyDocType AS MyDocAlias WHERE BookType.ISBN = '100'";
@@ -461,4 +507,75 @@ public class QueryTypesTest extends Abst
}
}
}
+
+ @Test
+ public void resolveTypeQualifiers1() throws Exception {
+ String statement = "SELECT Title FROM BookType WHERE IN_TREE(BookType, 'foo')";
+ CmisQueryWalker walker = traverseStatement(statement);
+ assertNotNull(walker);
+ assertEquals("BookType", queryObj.getTypeReference(pw.ids.get(0)));
+ }
+
+ @Test
+ public void resolveTypeQualifiers2() throws Exception {
+ String statement = "SELECT Title FROM BookType B WHERE IN_TREE(B, 'foo')";
+ CmisQueryWalker walker = traverseStatement(statement);
+ assertNotNull(walker);
+ assertEquals("B", queryObj.getTypeReference(pw.ids.get(0)));
+ }
+
+ @Test
+ public void resolveTypeQualifiers3() throws Exception {
+ String statement = "SELECT Title FROM BookType B WHERE IN_TREE(BookType, 'foo')";
+ CmisQueryWalker walker = traverseStatement(statement);
+ assertNotNull(walker);
+ assertEquals("B", queryObj.getTypeReference(pw.ids.get(0)));
+ }
+
+ @Test
+ public void resolveTypeQualifiers4() throws Exception {
+ String statement = "SELECT Title FROM BookType B WHERE IN_TREE(dummy, 'foo')";
+ try {
+ traverseStatement(statement);
+ fail("invalid correlation name should fail");
+ } catch (Exception e) {
+ assertTrue(e instanceof RecognitionException);
+ assertTrue(e.toString().contains(
+ "dummy is neither a type query name nor an alias"));
+ }
+ }
+
+ @Test
+ public void resolveTypeQualifiers5() throws Exception {
+ String statement = "SELECT B1.Title FROM BookType B1 JOIN BookType B2"
+ + " WHERE IN_TREE(B1, 'foo') OR IN_TREE(B2, 'bar')";
+ CmisQueryWalker walker = traverseStatement(statement);
+ assertNotNull(walker);
+ assertEquals("B1", queryObj.getTypeReference(pw.ids.get(0)));
+ assertEquals("B2", queryObj.getTypeReference(pw.ids.get(1)));
+ }
+
+ @Test
+ public void resolveTypeQualifiers6() throws Exception {
+ String statement = "SELECT B.Title FROM BookType B JOIN MyDocType D"
+ + " WHERE IN_TREE(MyDocType, 'foo')";
+ CmisQueryWalker walker = traverseStatement(statement);
+ assertNotNull(walker);
+ assertEquals("D", queryObj.getTypeReference(pw.ids.get(0)));
+ }
+
+ @Test
+ public void resolveTypeQualifiers7() throws Exception {
+ String statement = "SELECT B1.Title FROM BookType B1 JOIN BookType B2"
+ + " WHERE IN_TREE(BookType, 'foo')";
+ try {
+ traverseStatement(statement);
+ fail("ambiguous correlation name should fail");
+ } catch (Exception e) {
+ assertTrue(e instanceof RecognitionException);
+ assertTrue(e.toString().contains(
+ "BookType is an ambiguous type query name"));
+ }
+ }
+
}
Modified: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-support/src/main/antlr3/org/apache/chemistry/opencmis/server/support/query/CmisQueryWalker.g
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-support/src/main/antlr3/org/apache/chemistry/opencmis/server/support/query/CmisQueryWalker.g?rev=1096750&r1=1096749&r2=1096750&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-support/src/main/antlr3/org/apache/chemistry/opencmis/server/support/query/CmisQueryWalker.g (original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-support/src/main/antlr3/org/apache/chemistry/opencmis/server/support/query/CmisQueryWalker.g Tue Apr 26 13:34:32 2011
@@ -257,8 +257,17 @@ search_condition
queryObj.addWhereReference($mvcr.start, $mvcr.result);
}
| ^(CONTAINS qualifier? text_search_expression)
+ {
+ queryObj.addWhereTypeReference($qualifier.start, $qualifier.value);
+ }
| ^(IN_FOLDER qualifier? search_condition)
+ {
+ queryObj.addWhereTypeReference($qualifier.start, $qualifier.value);
+ }
| ^(IN_TREE qualifier? search_condition)
+ {
+ queryObj.addWhereTypeReference($qualifier.start, $qualifier.value);
+ }
| ^(IN column_reference in_value_list)
{
queryObj.addWhereReference($column_reference.start, $column_reference.result);
Modified: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-support/src/main/java/org/apache/chemistry/opencmis/server/support/query/AbstractPredicateWalker.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-support/src/main/java/org/apache/chemistry/opencmis/server/support/query/AbstractPredicateWalker.java?rev=1096750&r1=1096749&r2=1096750&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-support/src/main/java/org/apache/chemistry/opencmis/server/support/query/AbstractPredicateWalker.java (original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-support/src/main/java/org/apache/chemistry/opencmis/server/support/query/AbstractPredicateWalker.java Tue Apr 26 13:34:32 2011
@@ -131,6 +131,8 @@ public abstract class AbstractPredicateW
return walkList(node);
case CmisQlStrictLexer.COL:
return walkCol(node);
+ case CmisQlStrictLexer.ID:
+ return walkId(node);
default:
return walkOtherExpr(node);
}
@@ -293,4 +295,8 @@ public abstract class AbstractPredicateW
return null;
}
+ public Object walkId(Tree node) {
+ return null;
+ }
+
}
Modified: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-support/src/main/java/org/apache/chemistry/opencmis/server/support/query/PredicateWalker.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-support/src/main/java/org/apache/chemistry/opencmis/server/support/query/PredicateWalker.java?rev=1096750&r1=1096749&r2=1096750&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-support/src/main/java/org/apache/chemistry/opencmis/server/support/query/PredicateWalker.java (original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-support/src/main/java/org/apache/chemistry/opencmis/server/support/query/PredicateWalker.java Tue Apr 26 13:34:32 2011
@@ -89,4 +89,6 @@ public interface PredicateWalker extends
Object walkCol(Tree node);
+ Object walkId(Tree node);
+
}
Modified: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-support/src/main/java/org/apache/chemistry/opencmis/server/support/query/QueryObject.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-support/src/main/java/org/apache/chemistry/opencmis/server/support/query/QueryObject.java?rev=1096750&r1=1096749&r2=1096750&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-support/src/main/java/org/apache/chemistry/opencmis/server/support/query/QueryObject.java (original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-support/src/main/java/org/apache/chemistry/opencmis/server/support/query/QueryObject.java Tue Apr 26 13:34:32 2011
@@ -25,6 +25,7 @@ import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
import org.antlr.runtime.tree.Tree;
import org.apache.chemistry.opencmis.commons.definitions.TypeDefinition;
@@ -66,6 +67,7 @@ public class QueryObject {
// where part
protected final Map<Integer, CmisSelector> columnReferences = new HashMap<Integer, CmisSelector>();
+ protected final Map<Integer, String> typeReferences = new HashMap<Integer, String>();
// order by part
protected final List<SortSpec> sortSpecs = new ArrayList<SortSpec>();
@@ -135,6 +137,10 @@ public class QueryObject {
return columnReferences.get(token);
}
+ public String getTypeReference(Integer token) {
+ return typeReferences.get(token);
+ }
+
public String getErrorMessage() {
return errorMessage;
}
@@ -199,8 +205,8 @@ public class QueryObject {
return Collections.unmodifiableMap(froms);
}
- public String getTypeQueryName(String alias) {
- return froms.get(alias);
+ public String getTypeQueryName(String qualifier) {
+ return froms.get(qualifier);
}
public TypeDefinition getTypeDefinitionFromQueryName(String queryName) {
@@ -305,7 +311,6 @@ public class QueryObject {
public void addWhereReference(Tree node, CmisSelector reference) {
LOG.debug("add node to where: " + System.identityHashCode(node));
-
columnReferences.put(node.getTokenStartIndex(), reference);
whereReferences.add(reference);
}
@@ -314,6 +319,12 @@ public class QueryObject {
return Collections.unmodifiableList(whereReferences);
}
+ public void addWhereTypeReference(Tree node, String qualifier) {
+ if (node != null) {
+ typeReferences.put(node.getTokenStartIndex(), qualifier);
+ }
+ }
+
// ///////////////////////////////////////////////////////
// ORDER_BY part
@@ -396,6 +407,33 @@ public class QueryObject {
}
}
+ // Replace types used as qualifiers (IN_TREE, IN_FOLDER,
+ // CONTAINS) by their corresponding alias (correlation name)
+ for (Entry<Integer, String> en: typeReferences.entrySet()) {
+ Integer obj = en.getKey();
+ String qualifier = en.getValue();
+ String typeQueryName = getReferencedTypeQueryName(qualifier);
+ if (typeQueryName == null) {
+ throw new CmisQueryException(qualifier
+ + " is neither a type query name nor an alias.");
+ }
+ if (typeQueryName.equals(qualifier)) {
+ // try to find an alias for it
+ String alias = null;
+ for (Entry<String, String> e : froms.entrySet()) {
+ String q = e.getKey();
+ String tqn = e.getValue();
+ if (!tqn.equals(q) && typeQueryName.equals(tqn)) {
+ alias = q;
+ break;
+ }
+ }
+ if (alias != null) {
+ typeReferences.put(obj, alias);
+ }
+ }
+ }
+
return true;
} catch (CmisQueryException cqe) {
errorMessage = cqe.getMessage(); // preserve message
@@ -488,17 +526,22 @@ public class QueryObject {
// return type query name for a referenced column (which can be the name
// itself or an alias
- protected String getReferencedTypeQueryName(String typeQueryNameOrAlias) {
- String typeQueryName = froms.get(typeQueryNameOrAlias);
+ protected String getReferencedTypeQueryName(String qualifier) {
+ String typeQueryName = froms.get(qualifier);
if (null == typeQueryName) {
// if an alias was defined but still the original is used we have to
// search case: SELECT T.p FROM T AS TAlias
+ String q = null;
for (String tqn : froms.values()) {
- if (typeQueryNameOrAlias.equals(tqn)) {
- return tqn;
+ if (qualifier.equals(tqn)) {
+ if (q != null) {
+ throw new CmisQueryException(qualifier
+ + " is an ambiguous type query name.");
+ }
+ q = tqn;
}
}
- return null;
+ return q;
} else {
return typeQueryName;
}