You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@chemistry.apache.org by je...@apache.org on 2010/06/14 20:51:25 UTC

svn commit: r954587 [3/4] - in /incubator/chemistry/opencmis/trunk: chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/dataobjects/ chemistry-opencmis-server/chemistry-opencmis-server-inm...

Added: incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/test/java/org/apache/chemistry/opencmis/inmemory/query/AbstractQueryTest.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/test/java/org/apache/chemistry/opencmis/inmemory/query/AbstractQueryTest.java?rev=954587&view=auto
==============================================================================
--- incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/test/java/org/apache/chemistry/opencmis/inmemory/query/AbstractQueryTest.java (added)
+++ incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/test/java/org/apache/chemistry/opencmis/inmemory/query/AbstractQueryTest.java Mon Jun 14 18:51:24 2010
@@ -0,0 +1,199 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.chemistry.opencmis.inmemory.query;
+
+import static org.junit.Assert.fail;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.antlr.runtime.ANTLRInputStream;
+import org.antlr.runtime.CharStream;
+import org.antlr.runtime.CommonTokenStream;
+import org.antlr.runtime.RecognitionException;
+import org.antlr.runtime.TokenSource;
+import org.antlr.runtime.TokenStream;
+import org.antlr.runtime.tree.CommonTree;
+import org.antlr.runtime.tree.CommonTreeNodeStream;
+import org.antlr.runtime.tree.Tree;
+import org.apache.chemistry.opencmis.commons.definitions.PropertyBooleanDefinition;
+import org.apache.chemistry.opencmis.commons.definitions.PropertyDefinition;
+import org.apache.chemistry.opencmis.commons.definitions.PropertyStringDefinition;
+import org.apache.chemistry.opencmis.commons.definitions.TypeDefinition;
+import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyBooleanDefinitionImpl;
+import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyDateTimeDefinitionImpl;
+import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyIntegerDefinitionImpl;
+import org.apache.chemistry.opencmis.inmemory.types.InMemoryDocumentTypeDefinition;
+import org.apache.chemistry.opencmis.inmemory.types.PropertyCreationHelper;
+import org.apache.chemistry.opencmis.server.support.query.CMISQLParser;
+
+public abstract class AbstractQueryTest {
+
+    protected CommonTree parserTree; // the ANTLR tree after parsing phase
+    protected CommonTree walkerTree; // the ANTLR tree after walking phase
+    protected QueryObject queryObj;
+    protected TypeDefinition myType, myTypeCopy, bookType;
+
+    protected static final String MY_DOC_TYPE = "MyDocType";
+    protected static final String MY_DOC_TYPE_COPY = "MyDocTypeCopy";
+    protected static final String BOOL_PROP = "MyBooleanProp";
+    protected static final String STRING_PROP = "MyStringProp";
+    protected static final String INT_PROP = "MyIntegerProp";
+
+    protected static final String BOOK_TYPE = "BookType";
+    protected static final String TITLE_PROP = "Title";
+    protected static final String AUTHOR_PROP = "Author";
+    protected static final String ISBN_PROP = "ISBN";
+    protected static final String PUB_DATE_PROP = "PublishingDate";
+    
+    protected void setUp(QueryObject qo) throws Exception {
+            queryObj = qo;
+    }
+
+    protected void tearDown() throws Exception {
+    }
+
+    protected CmisQueryWalker getWalker(String statement) throws UnsupportedEncodingException, IOException, RecognitionException {
+        CharStream input = new ANTLRInputStream(new ByteArrayInputStream(statement.getBytes("UTF-8")));
+        TokenSource lexer = new CMISQLLexerStrict(input);
+        TokenStream tokens = new CommonTokenStream(lexer);
+        CMISQLParserStrict parser = new CMISQLParserStrict(tokens);
+
+        CMISQLParserStrict.query_return parsedStatement = parser.query();
+        if (parser.errorMessage != null) {
+            throw new RuntimeException("Cannot parse query: " + statement + " (" + parser.errorMessage + ")");
+        }
+        parserTree = (CommonTree) parsedStatement.getTree();            
+        // printTree(tree);
+
+        CommonTreeNodeStream nodes = new CommonTreeNodeStream(parserTree);
+        nodes.setTokenStream(tokens);
+        CmisQueryWalker walker = new CmisQueryWalker(nodes);
+        return walker;
+    }
+
+    protected CmisQueryWalker traverseStatement(String statement) throws UnsupportedEncodingException, IOException, RecognitionException {
+        CmisQueryWalker walker = getWalker(statement);
+        walker.query(queryObj);
+        String errMsg = walker.getErrorMessageString();
+        if (null != errMsg) {
+            fail("Walking of statement failed with error: \n   " + errMsg + 
+                    "\n   Statement was: " + statement);
+        }
+        walkerTree = (CommonTree) walker.getTreeNodeStream().getTreeSource();
+        return walker;
+    }
+
+    protected CmisQueryWalker traverseStatementAndCatchExc(String statement) {
+        try {
+            return traverseStatement(statement);
+        } catch (RecognitionException e) {
+            fail("Walking of statement failed with RecognitionException error: \n   " + e); 
+            return null;
+        } catch (Exception e) {
+            fail("Walking of statement failed with other exception: \n   " + e); 
+            return null;
+        }
+    }
+    
+    protected Tree getWhereTree(Tree root) {
+        int count = root.getChildCount();
+        for (int i=0; i<count; i++) {
+            Tree child = root.getChild(i);
+            if (child.getType() == CMISQLLexerStrict.WHERE) {
+                return child;
+            }
+        }
+        return null;
+    }
+
+    // Helper to create some types for testing
+
+    protected  List<TypeDefinition> createTypes() {
+
+        List<TypeDefinition> typeDefs = new ArrayList<TypeDefinition>();
+        
+        // First test type
+        InMemoryDocumentTypeDefinition cmisType = new InMemoryDocumentTypeDefinition(MY_DOC_TYPE,
+                "Document Type for Validation", InMemoryDocumentTypeDefinition.getRootDocumentType());
+
+        Map<String, PropertyDefinition<?>> propertyDefinitions = new HashMap<String, PropertyDefinition<?>>();
+
+        PropertyBooleanDefinition prop1 = PropertyCreationHelper.createBooleanDefinition(BOOL_PROP,
+        "Sample Boolean Property");
+        ((PropertyBooleanDefinitionImpl) prop1).setIsRequired(true);
+        propertyDefinitions.put(prop1.getId(), prop1);
+
+        PropertyStringDefinition prop2 = PropertyCreationHelper.createStringDefinition(STRING_PROP,
+        "Sample String Property");
+        propertyDefinitions.put(prop2.getId(), prop2);
+
+        PropertyIntegerDefinitionImpl prop3 = PropertyCreationHelper.createIntegerDefinition(INT_PROP,
+        "Sample Integer Property");
+        propertyDefinitions.put(prop2.getId(), prop2);
+
+        cmisType.setPropertyDefinitions(propertyDefinitions);
+
+        typeDefs.add(cmisType);
+        myType = cmisType;
+        
+        // add another type definition with exactly the same properties
+        cmisType = new InMemoryDocumentTypeDefinition(MY_DOC_TYPE_COPY,
+                "Document Type Duplicated", InMemoryDocumentTypeDefinition.getRootDocumentType());
+        cmisType.setPropertyDefinitions(propertyDefinitions); // add same properties
+        typeDefs.add(cmisType);
+        myTypeCopy = cmisType;
+
+
+        // Second test type
+
+        cmisType = new InMemoryDocumentTypeDefinition(BOOK_TYPE,
+                "Book Document Type", InMemoryDocumentTypeDefinition.getRootDocumentType());
+
+        propertyDefinitions = new HashMap<String, PropertyDefinition<?>>();
+
+        prop2 = PropertyCreationHelper.createStringDefinition(TITLE_PROP, "Title of Book");
+        propertyDefinitions.put(prop2.getId(), prop2);
+
+        prop2 = PropertyCreationHelper.createStringDefinition(AUTHOR_PROP, "Author of Book");
+        propertyDefinitions.put(prop2.getId(), prop2);
+
+        prop3 = PropertyCreationHelper.createIntegerDefinition(ISBN_PROP,
+        "ISBN of Book");
+        propertyDefinitions.put(prop3.getId(), prop3);
+
+        PropertyDateTimeDefinitionImpl prop4 = PropertyCreationHelper.createDateTimeDefinition(PUB_DATE_PROP,
+        "Publishing Date of Book");
+        propertyDefinitions.put(prop4.getId(), prop4);
+
+        cmisType.setPropertyDefinitions(propertyDefinitions);
+        
+        typeDefs.add(cmisType);
+        bookType = cmisType;
+        
+        return typeDefs;
+    }
+
+
+}

Added: incubator/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/incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/test/java/org/apache/chemistry/opencmis/inmemory/query/EvalQueryTest.java?rev=954587&view=auto
==============================================================================
--- incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/test/java/org/apache/chemistry/opencmis/inmemory/query/EvalQueryTest.java (added)
+++ incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/test/java/org/apache/chemistry/opencmis/inmemory/query/EvalQueryTest.java Mon Jun 14 18:51:24 2010
@@ -0,0 +1,386 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.chemistry.opencmis.inmemory.query;
+
+import static org.apache.chemistry.opencmis.inmemory.UnitTestTypeSystemCreator.COMPLEX_TYPE;
+import static org.apache.chemistry.opencmis.inmemory.UnitTestTypeSystemCreator.PROP_ID_BOOLEAN;
+import static org.apache.chemistry.opencmis.inmemory.UnitTestTypeSystemCreator.PROP_ID_DATETIME;
+import static org.apache.chemistry.opencmis.inmemory.UnitTestTypeSystemCreator.PROP_ID_DECIMAL;
+import static org.apache.chemistry.opencmis.inmemory.UnitTestTypeSystemCreator.PROP_ID_INT;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.chemistry.opencmis.commons.PropertyIds;
+import org.apache.chemistry.opencmis.commons.data.ObjectData;
+import org.apache.chemistry.opencmis.commons.data.ObjectList;
+import org.apache.chemistry.opencmis.commons.enums.IncludeRelationships;
+import org.apache.chemistry.opencmis.inmemory.AbstractServiceTst;
+import org.apache.chemistry.opencmis.inmemory.UnitTestTypeSystemCreator;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class EvalQueryTest extends AbstractServiceTst {
+    
+    private static Log log = LogFactory.getLog(EvalQueryTest.class);
+    
+    @Before
+    public void setUp() throws Exception {
+
+        // initialize query object with type manager
+        super.setTypeCreatorClass(UnitTestTypeSystemCreator.class.getName());
+        super.setUp();
+        //create test data
+        QueryTestDataCreator dataCreator = new QueryTestDataCreator(fRepositoryId, fRootFolderId, fObjSvc );
+        dataCreator.createTestData();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    @Test
+    public void testAll() {
+        String statement = "SELECT * FROM cmis:document";
+        ObjectList res = doQuery(statement);
+        assertEquals(5, res.getObjects().size());
+        assertTrue(resultContains("alpha", res));
+        assertFalse(resultContains("jens", res));
+    }
+    
+    //////////////////////////////////////////////////////////////////////
+    // Boolean tests
+    
+    @Test
+    public void testBooleanEquals() {
+        String statement = "SELECT * FROM " + COMPLEX_TYPE + " WHERE " + PROP_ID_BOOLEAN + "= true";
+        ObjectList res = doQuery(statement);
+        assertEquals(3, res.getObjects().size());
+        assertTrue(resultContains("alpha", res));        
+        assertTrue(resultContains("gamma", res));        
+        assertTrue(resultContains("delta", res));        
+    }
+    
+    @Test
+    public void testBooleanNotEquals() {
+        String statement = "SELECT * FROM " + COMPLEX_TYPE + " WHERE " + PROP_ID_BOOLEAN + "= false";
+        ObjectList res = doQuery(statement);
+        assertEquals(2, res.getObjects().size());
+        assertTrue(resultContains("beta", res));        
+        assertTrue(resultContains("epsilon", res));        
+    }
+    
+    //////////////////////////////////////////////////////////////////////
+    // Integer tests
+    
+    @Test
+    public void testIntegerEquals() {
+        String statement = "SELECT * FROM " + COMPLEX_TYPE + " WHERE " + PROP_ID_INT + "= 100";
+        ObjectList res = doQuery(statement);
+        assertEquals(1, res.getObjects().size());
+        assertTrue(resultContains("epsilon", res));        
+    }
+    
+    @Test
+    public void testIntegerNotEquals() {
+        String statement = "SELECT * FROM " + COMPLEX_TYPE + " WHERE " + PROP_ID_INT + "<> 100";
+        ObjectList res = doQuery(statement);
+        assertEquals(4, res.getObjects().size());
+        assertTrue(resultContains("alpha", res));        
+        assertTrue(resultContains("beta", res));        
+        assertTrue(resultContains("gamma", res));        
+        assertTrue(resultContains("delta", res));        
+    }
+
+    @Test
+    public void testIntegerLess() {
+        String statement = "SELECT * FROM " + COMPLEX_TYPE + " WHERE " + PROP_ID_INT + "< 0";
+        ObjectList res = doQuery(statement);
+        assertEquals(2, res.getObjects().size());
+        assertTrue(resultContains("alpha", res));        
+        assertTrue(resultContains("beta", res));        
+    }
+
+    @Test
+    public void testIntegerLessOrEqual() {
+        String statement = "SELECT * FROM " + COMPLEX_TYPE + " WHERE " + PROP_ID_INT + "<= 0";
+        ObjectList res = doQuery(statement);
+        assertEquals(3, res.getObjects().size());
+        assertTrue(resultContains("alpha", res));        
+        assertTrue(resultContains("beta", res));        
+        assertTrue(resultContains("gamma", res));        
+    }
+    
+    @Test
+    public void testIntegerGreater() {
+        String statement = "SELECT * FROM " + COMPLEX_TYPE + " WHERE " + PROP_ID_INT + "> 0";
+        ObjectList res = doQuery(statement);
+        assertEquals(2, res.getObjects().size());
+        assertTrue(resultContains("delta", res));        
+        assertTrue(resultContains("epsilon", res));        
+    }
+
+    @Test
+    public void testIntegerGreaterOrEqual() {
+        String statement = "SELECT * FROM " + COMPLEX_TYPE + " WHERE " + PROP_ID_INT + ">= 0";
+        ObjectList res = doQuery(statement);
+        assertEquals(3, res.getObjects().size());
+        assertTrue(resultContains("gamma", res));        
+        assertTrue(resultContains("delta", res));        
+        assertTrue(resultContains("epsilon", res));        
+    }
+
+    //////////////////////////////////////////////////////////////////////
+    // Decimal tests
+    
+    @Test
+    public void testDecimalEquals() {
+        String statement = "SELECT * FROM " + COMPLEX_TYPE + " WHERE " + PROP_ID_DECIMAL + "= 1.23456E-6";
+        ObjectList res = doQuery(statement);
+        assertEquals(1, res.getObjects().size());
+        assertTrue(resultContains("delta", res));        
+    }
+    
+    @Test
+    public void testDecimalNotEquals() {
+        String statement = "SELECT * FROM " + COMPLEX_TYPE + " WHERE " + PROP_ID_DECIMAL + "<> 1.23456E-6";
+        ObjectList res = doQuery(statement);
+        assertEquals(4, res.getObjects().size());
+        assertTrue(resultContains("alpha", res));        
+        assertTrue(resultContains("beta", res));        
+        assertTrue(resultContains("gamma", res));        
+        assertTrue(resultContains("epsilon", res));        
+    }
+
+    @Test
+    public void testDecimalLess() {
+        String statement = "SELECT * FROM " + COMPLEX_TYPE + " WHERE " + PROP_ID_DECIMAL + "< 1.23456E-6";
+        ObjectList res = doQuery(statement);
+        assertEquals(2, res.getObjects().size());
+        assertTrue(resultContains("alpha", res));        
+        assertTrue(resultContains("beta", res));        
+    }
+
+    @Test
+    public void testDecimalLessOrEqual() {
+        String statement = "SELECT * FROM " + COMPLEX_TYPE + " WHERE " + PROP_ID_DECIMAL + "<= 1.23456E-6";
+        ObjectList res = doQuery(statement);
+        assertEquals(3, res.getObjects().size());
+        assertTrue(resultContains("alpha", res));        
+        assertTrue(resultContains("beta", res));        
+        assertTrue(resultContains("delta", res));        
+    }
+    
+    @Test
+    public void testDecimalGreater() {
+        String statement = "SELECT * FROM " + COMPLEX_TYPE + " WHERE " + PROP_ID_DECIMAL + "> 1.23456E-6";
+        ObjectList res = doQuery(statement);
+        assertEquals(2, res.getObjects().size());
+        assertTrue(resultContains("gamma", res));        
+        assertTrue(resultContains("epsilon", res));        
+    }
+
+    @Test
+    public void testDecimalGreaterOrEqual() {
+        String statement = "SELECT * FROM " + COMPLEX_TYPE + " WHERE " + PROP_ID_DECIMAL + ">= 1.23456E-6";
+        ObjectList res = doQuery(statement);
+        assertEquals(3, res.getObjects().size());
+        assertTrue(resultContains("gamma", res));        
+        assertTrue(resultContains("delta", res));        
+        assertTrue(resultContains("epsilon", res));        
+    }
+    
+    //////////////////////////////////////////////////////////////////////
+    // DateTime tests
+    
+    @Test
+    public void testDateEquals() {
+        String statement = "SELECT * FROM " + COMPLEX_TYPE + " WHERE " + PROP_ID_DATETIME + "= TIMESTAMP '2038-01-20T00:00:00.000Z'";
+        ObjectList res = doQuery(statement);
+        assertEquals(1, res.getObjects().size());
+        assertTrue(resultContains("delta", res));        
+    }
+    
+    @Test
+    public void testDateNotEquals() {
+        String statement = "SELECT * FROM " + COMPLEX_TYPE + " WHERE " + PROP_ID_DATETIME + "<> TIMESTAMP '2038-01-20T00:00:00.000Z'";
+        ObjectList res = doQuery(statement);
+        assertEquals(4, res.getObjects().size());
+        assertTrue(resultContains("alpha", res));        
+        assertTrue(resultContains("beta", res));        
+        assertTrue(resultContains("gamma", res));        
+        assertTrue(resultContains("epsilon", res));        
+    }
+
+    @Test
+    public void testDateLess() {
+        String statement = "SELECT * FROM " + COMPLEX_TYPE + " WHERE " + PROP_ID_DATETIME + "< TIMESTAMP '2038-01-20T00:00:00.000Z'";
+        ObjectList res = doQuery(statement);
+        assertEquals(3, res.getObjects().size());
+        assertTrue(resultContains("alpha", res));        
+        assertTrue(resultContains("beta", res));        
+        assertTrue(resultContains("gamma", res));        
+    }
+
+    @Test
+    public void testDateLessOrEquals() {
+        String statement = "SELECT * FROM " + COMPLEX_TYPE + " WHERE " + PROP_ID_DATETIME + "<= TIMESTAMP '2038-01-20T00:00:00.000Z'";
+        ObjectList res = doQuery(statement);
+        assertEquals(4, res.getObjects().size());
+        assertTrue(resultContains("alpha", res));        
+        assertTrue(resultContains("beta", res));        
+        assertTrue(resultContains("gamma", res));        
+        assertTrue(resultContains("delta", res));        
+    }
+
+    @Test
+    public void testDategreater() {
+        String statement = "SELECT * FROM " + COMPLEX_TYPE + " WHERE " + PROP_ID_DATETIME + "> TIMESTAMP '2038-01-20T00:00:00.000Z'";
+        ObjectList res = doQuery(statement);
+        assertEquals(1, res.getObjects().size());
+        assertTrue(resultContains("epsilon", res));        
+    }
+
+    //    @Test
+    public void testDateGreaterOrEqual() {
+        String statement = "SELECT * FROM " + COMPLEX_TYPE + " WHERE " + PROP_ID_DATETIME + ">= TIMESTAMP '2038-01-20T00:00:00.000Z'";
+        ObjectList res = doQuery(statement);
+        assertEquals(2, res.getObjects().size());
+        assertTrue(resultContains("delta", res));        
+        assertTrue(resultContains("epsilon", res));        
+    }
+    
+    ////////////////////////////////////////////////////////////////////
+    // String tests
+
+    @Test
+    public void testStringEquals() {
+        String statement = "SELECT * FROM " + COMPLEX_TYPE + " WHERE " + UnitTestTypeSystemCreator.PROP_ID_STRING + "= 'Alpha'";
+        ObjectList res = doQuery(statement);
+        assertEquals(1, res.getObjects().size());
+        assertTrue(resultContains("alpha", res));        
+    }
+    
+    @Test
+    public void testStringNotEquals() {
+        String statement = "SELECT * FROM " + COMPLEX_TYPE + " WHERE " + UnitTestTypeSystemCreator.PROP_ID_STRING + "<> 'Gamma'";
+        ObjectList res = doQuery(statement);
+        assertEquals(4, res.getObjects().size());
+        assertTrue(resultContains("alpha", res));        
+        assertTrue(resultContains("beta", res));        
+        assertTrue(resultContains("delta", res));        
+        assertTrue(resultContains("epsilon", res));        
+    }
+
+    @Test
+    public void testStringLess() {
+        String statement = "SELECT * FROM " + COMPLEX_TYPE + " WHERE " + UnitTestTypeSystemCreator.PROP_ID_STRING + "< 'Delta'";
+        ObjectList res = doQuery(statement);
+        assertEquals(2, res.getObjects().size());
+        assertTrue(resultContains("alpha", res));        
+        assertTrue(resultContains("beta", res));        
+    }
+
+    @Test
+    public void testStringLessOrEquals() {
+        String statement = "SELECT * FROM " + COMPLEX_TYPE + " WHERE " + UnitTestTypeSystemCreator.PROP_ID_STRING + "<= 'Delta'";
+        ObjectList res = doQuery(statement);
+        assertEquals(3, res.getObjects().size());
+        assertTrue(resultContains("alpha", res));        
+        assertTrue(resultContains("beta", res));        
+        assertTrue(resultContains("delta", res));        
+    }
+    
+    @Test
+    public void testStringGreater() {
+        String statement = "SELECT * FROM " + COMPLEX_TYPE + " WHERE " + UnitTestTypeSystemCreator.PROP_ID_STRING + "> 'Delta'";
+        ObjectList res = doQuery(statement);
+        assertEquals(2, res.getObjects().size());
+        assertTrue(resultContains("gamma", res));        
+        assertTrue(resultContains("epsilon", res));        
+    }
+    
+    @Test
+    public void testStringGreaterOrEquals() {
+        String statement = "SELECT * FROM " + COMPLEX_TYPE + " WHERE " + UnitTestTypeSystemCreator.PROP_ID_STRING + ">= 'Delta'";
+        ObjectList res = doQuery(statement);
+        assertEquals(3, res.getObjects().size());
+        assertTrue(resultContains("gamma", res));        
+        assertTrue(resultContains("delta", res));        
+        assertTrue(resultContains("epsilon", res));        
+    }
+
+    ////////////////////////////////////////////////////////////////////
+    // Boolean condition tests
+    
+    @Test
+    public void testAnd() {
+        String statement = "SELECT * FROM " + COMPLEX_TYPE + " WHERE " + PROP_ID_INT + "= 50 AND " + PROP_ID_BOOLEAN + "= true";
+        ObjectList res = doQuery(statement);
+        assertEquals(1, res.getObjects().size());
+        assertTrue(resultContains("delta", res));        
+
+        statement = "SELECT * FROM " + COMPLEX_TYPE + " WHERE " + PROP_ID_INT + "= 50 AND " + PROP_ID_BOOLEAN + "= false";
+        res = doQuery(statement);
+        assertEquals(0, res.getObjects().size());
+    }
+
+    @Test
+    public void testOr() {
+        String statement = "SELECT * FROM " + COMPLEX_TYPE + " WHERE " + PROP_ID_INT + "= -50 OR " + PROP_ID_BOOLEAN + "= false";
+        ObjectList res = doQuery(statement);
+        assertEquals(2, res.getObjects().size());
+        assertTrue(resultContains("beta", res));        
+        assertTrue(resultContains("epsilon", res));        
+    }
+
+    @Test
+    public void testNot() {
+        String statement = "SELECT * FROM " + COMPLEX_TYPE + " WHERE NOT " + PROP_ID_INT + "= 50";
+        ObjectList res = doQuery(statement);
+        assertEquals(4, res.getObjects().size());
+        assertTrue(resultContains("alpha", res));        
+        assertTrue(resultContains("beta", res));        
+        assertTrue(resultContains("gamma", res));        
+        assertTrue(resultContains("epsilon", res));        
+    }
+
+    private ObjectList doQuery(String queryString) {
+        log.debug("\nExecuting query: " + queryString);
+        ObjectList res = fDiscSvc.query(fRepositoryId, queryString, false, false,
+                IncludeRelationships.NONE, null, null, null, null);
+        log.debug("Query result, number of matching objects: " + res.getNumItems());
+        for (ObjectData od : res.getObjects())
+            log.debug("Found matching object: " + od.getProperties().getProperties().get(PropertyIds.NAME).getFirstValue());
+        return res;
+    }
+
+    private boolean resultContains(String name, ObjectList results) {
+        for (ObjectData od : results.getObjects()) {
+            String nameProp = (String) od.getProperties().getProperties().get(PropertyIds.NAME).getFirstValue();
+            if (name.equals(nameProp))
+                return true;
+        }
+        return false;
+    }
+}

Added: incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/test/java/org/apache/chemistry/opencmis/inmemory/query/ProcessQueryTest.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/test/java/org/apache/chemistry/opencmis/inmemory/query/ProcessQueryTest.java?rev=954587&view=auto
==============================================================================
--- incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/test/java/org/apache/chemistry/opencmis/inmemory/query/ProcessQueryTest.java (added)
+++ incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/test/java/org/apache/chemistry/opencmis/inmemory/query/ProcessQueryTest.java Mon Jun 14 18:51:24 2010
@@ -0,0 +1,538 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.chemistry.opencmis.inmemory.query;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.GregorianCalendar;
+import java.util.HashMap;
+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;
+import org.apache.chemistry.opencmis.inmemory.TypeManagerImpl;
+import org.apache.chemistry.opencmis.server.support.query.CalendarHelper;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class ProcessQueryTest extends AbstractQueryTest {
+    
+    static private class TestQueryProcessor implements IQueryConditionProcessor {
+
+        private static Log log = LogFactory.getLog(ProcessQueryTest.class);
+        
+        private static final String ON_START = "onStartWasCalled";
+        private static final String ON_STOP = "onStopWasCalled";
+        private static final String ON_EQUALS_WASCALLED = "onEqualsWasCalled";
+        private static final String ON_NOT_EQUALS = "onNotEqualsWasCalled";
+        private static final String ON_GREATER_THAN = "onGreaterThanWasCalled";
+        private static final String ON_GREATER_OR_EQUALS ="onGreaterOrEqualsWasCalled";
+        private static final String ON_LESS_THAN = "onLessThanWasCalled";
+        private static final String ON_LESS_OR_EQUALS = "onLessOrEqualsWasCalled";
+        private static final String ON_NOT = "onNotWasCalled";
+        private static final String ON_AND = "onAndWasCalled";
+        private static final String ON_OR = "onOrWasCalled";
+        private static final String ON_IN = "onInWasCalled";
+        private static final String ON_NOT_IN = "onNotInWasCalled";
+        private static final String ON_IN_ANY = "onInAnyWasCalled";
+        private static final String ON_NOT_IN_ANY ="onNotInAnyWasCalled";
+        private static final String ON_EQ_ANY = "onEqAnyWasCalled";
+        private static final String ON_IS_NULL = "onIsNullWasCalled";
+        private static final String ON_IS_NOT_NULL ="onIsNotNullWasCalled";
+        private static final String ON_IS_LIKE = "onIsLikeWasCalled";
+        private static final String ON_IS_NOT_LIKE = "onIsNotLikeWasCalled";
+        private static final String ON_CONTAINS  = "onContainsWasCalled";
+        private static final String ON_IN_FOLDER  = "onInFolderWasCalled";
+        private static final String ON_IN_TREE  = "onInTreeWasCalled";
+        private static final String ON_SCORE = "onScoreWasCalled";
+
+        
+        final Map<String, Boolean> rulesTrackerMap = 
+            new HashMap<String, Boolean>() {
+                private static final long serialVersionUID = 1L;
+            { 
+                put(ON_START, false);
+                put(ON_STOP, false);
+                put(ON_EQUALS_WASCALLED, false);
+                put(ON_NOT_EQUALS, false);
+                put(ON_GREATER_THAN, false);
+                put(ON_GREATER_OR_EQUALS, false);
+                put(ON_LESS_THAN, false);
+                put(ON_LESS_OR_EQUALS, false);
+                put(ON_NOT, false);
+                put(ON_AND, false);
+                put(ON_OR, false);
+                put(ON_IN, false);
+                put(ON_NOT_IN, false);
+                put(ON_IN_ANY, false);
+                put(ON_NOT_IN_ANY, false);
+                put(ON_EQ_ANY, false);
+                put(ON_IS_NULL, false);
+                put(ON_IS_NOT_NULL, false);
+                put(ON_IS_LIKE, false);
+                put(ON_IS_NOT_LIKE, false);
+                put(ON_CONTAINS, false);
+                put(ON_IN_FOLDER, false);
+                put(ON_IN_TREE, false);
+                put(ON_SCORE, false);
+           }};
+        
+       public TestQueryProcessor() {
+        }
+        
+
+       public void onStartProcessing(Tree node) {
+            log.debug("TestQueryProcessor:onStartProcessing()");
+            rulesTrackerMap.put(ON_START, true);
+            assertEquals(CMISQLLexerStrict.WHERE, node.getType());
+       }
+
+       public void onStopProcessing() {
+           log.debug("TestQueryProcessor:onStopProcessing()");
+           rulesTrackerMap.put(ON_STOP, true);
+       }
+
+
+       public void onEquals(Tree eqNode, Tree leftNode, Tree rightNode) {
+           rulesTrackerMap.put(ON_EQUALS_WASCALLED, true);
+           assertEquals(CMISQLLexerStrict.EQ, eqNode.getType());
+           assertTrue(CMISQLLexerStrict.COL==leftNode.getType() || CMISQLLexerStrict.SCORE==leftNode.getType());
+           assertTrue(isLiteral(rightNode));
+       }
+
+       public void onNotEquals(Tree neNode, Tree leftNode, Tree rightNode) {
+           rulesTrackerMap.put(ON_NOT_EQUALS, true);
+           assertEquals(CMISQLLexerStrict.NEQ, neNode.getType());
+           assertEquals(CMISQLLexerStrict.COL, leftNode.getType());
+           assertTrue(isLiteral(rightNode));
+           Object value=onLiteral(rightNode, Integer.class);
+           assertEquals(100, value);            
+       }
+
+       public void onLessOrEquals(Tree leqNode, Tree leftNode, Tree rightNode) {
+           rulesTrackerMap.put(ON_LESS_OR_EQUALS, true);
+           assertEquals(CMISQLLexerStrict.LTEQ, leqNode.getType());
+           assertEquals(CMISQLLexerStrict.COL, leftNode.getType());
+           assertTrue(isLiteral(rightNode));
+           Object value=onLiteral(rightNode, Integer.class);
+           assertEquals(100, value);            
+       }
+
+       public void onLessThan(Tree ltNode, Tree leftNode, Tree rightNode) {
+           rulesTrackerMap.put(ON_LESS_THAN, true);
+           assertEquals(CMISQLLexerStrict.LT, ltNode.getType());
+           assertEquals(CMISQLLexerStrict.COL, leftNode.getType());
+           assertTrue(isLiteral(rightNode));
+           Object value=onLiteral(rightNode, Integer.class);
+           assertEquals(100, value);            
+       }
+
+       public void onGreaterOrEquals(Tree geNode, Tree leftNode, Tree rightNode) {
+           rulesTrackerMap.put(ON_GREATER_OR_EQUALS, true);
+           assertEquals(CMISQLLexerStrict.GTEQ, geNode.getType());
+           assertEquals(CMISQLLexerStrict.COL, leftNode.getType());
+           assertTrue(isLiteral(rightNode));
+           Object value=onLiteral(rightNode, Integer.class);
+           assertEquals(100, value);            
+       }
+
+       public void onGreaterThan(Tree gtNode, Tree leftNode, Tree rightNode) {
+           rulesTrackerMap.put(ON_GREATER_THAN, true);
+           assertEquals(CMISQLLexerStrict.GT, gtNode.getType());
+           assertEquals(CMISQLLexerStrict.COL, leftNode.getType());
+           assertTrue(isLiteral(rightNode));
+           Object value=onLiteral(rightNode, Integer.class);
+           assertEquals(100, value);            
+       }
+
+       public void onNot(Tree opNode, Tree leftNode) {
+           rulesTrackerMap.put(ON_NOT, true);
+           assertEquals(CMISQLLexerStrict.NOT, opNode.getType());
+       }
+
+       public void onAnd(Tree opNode, Tree leftNode, Tree rightNode) {
+           assertEquals(CMISQLLexerStrict.AND, opNode.getType());
+           rulesTrackerMap.put(ON_AND, true);
+       }
+
+       public void onOr(Tree opNode, Tree leftNode, Tree rightNode) {
+           assertEquals(CMISQLLexerStrict.OR, opNode.getType());
+           rulesTrackerMap.put(ON_OR, true);
+       }
+
+       public void onIn(Tree opNode, Tree colNode, Tree listNode) {
+           assertEquals(CMISQLLexerStrict.IN, opNode.getType());
+           assertEquals(CMISQLLexerStrict.COL, colNode.getType());
+           assertEquals(CMISQLLexerStrict.IN_LIST, listNode.getType());
+           Object value=onLiteral(listNode.getChild(0), String.class);
+           assertEquals("'Joe'", value);            
+           value=onLiteral(listNode.getChild(1), String.class);
+           assertEquals("'Jim'", value);            
+           rulesTrackerMap.put(ON_IN, true);
+       }
+
+       public void onNotIn(Tree node, Tree colNode, Tree listNode) {
+           assertEquals(CMISQLLexerStrict.NOT_IN, node.getType());
+           assertEquals(CMISQLLexerStrict.COL, colNode.getType());
+           assertEquals(CMISQLLexerStrict.IN_LIST, listNode.getType());
+           Object value=onLiteral(listNode.getChild(0), String.class);
+           assertEquals("'Joe'", value);            
+           value=onLiteral(listNode.getChild(1), String.class);
+           assertEquals("'Jim'", value);            
+           rulesTrackerMap.put(ON_NOT_IN, true);
+       }
+
+       public void onEqAny(Tree node, Tree literalNode, Tree colNode) {
+           assertEquals(CMISQLLexerStrict.EQ_ANY, node.getType());
+           assertEquals(CMISQLLexerStrict.COL, colNode.getType());
+           assertTrue(isLiteral(literalNode));
+           Object value=onLiteral(literalNode, String.class);
+           assertEquals("'Joe'", value);            
+           rulesTrackerMap.put(ON_EQ_ANY, true);
+       }
+
+       public void onInAny(Tree node, Tree colNode, Tree listNode) {
+           assertEquals(CMISQLLexerStrict.IN_ANY, node.getType());
+           assertEquals(CMISQLLexerStrict.COL, colNode.getType());
+           assertEquals(CMISQLLexerStrict.IN_LIST, listNode.getType());
+           Object value=onLiteral(listNode.getChild(0), String.class);
+           assertEquals("'Joe'", value);            
+           value=onLiteral(listNode.getChild(1), String.class);
+           assertEquals("'Jim'", value);            
+           rulesTrackerMap.put(ON_IN_ANY, true);
+       }
+
+       public void onNotInAny(Tree node, Tree colNode, Tree listNode) {
+           assertEquals(CMISQLLexerStrict.NOT_IN_ANY, node.getType());
+           assertEquals(CMISQLLexerStrict.COL, colNode.getType());
+           assertEquals(CMISQLLexerStrict.IN_LIST, listNode.getType());
+           Object value=onLiteral(listNode.getChild(0), String.class);
+           assertEquals("'Joe'", value);            
+           value=onLiteral(listNode.getChild(1), String.class);
+           assertEquals("'Jim'", value);            
+           rulesTrackerMap.put(ON_NOT_IN_ANY, true);
+       }
+
+       public void onIsNull(Tree nullNode, Tree colNode) {
+           assertEquals(CMISQLLexerStrict.COL, colNode.getType());
+           assertEquals(CMISQLLexerStrict.IS_NULL, nullNode.getType());
+           rulesTrackerMap.put(ON_IS_NULL, true);
+       }
+
+       public void onIsNotNull(Tree notNullNode, Tree colNode) {
+           assertEquals(CMISQLLexerStrict.COL, colNode.getType());
+           assertEquals(CMISQLLexerStrict.IS_NOT_NULL, notNullNode.getType());
+           rulesTrackerMap.put(ON_IS_NOT_NULL, true);
+       }
+
+       public void onIsLike(Tree node, Tree colNode, Tree stringNode) {
+           assertEquals(CMISQLLexerStrict.LIKE, node.getType());
+           assertEquals(CMISQLLexerStrict.COL, colNode.getType());
+           assertEquals(CMISQLLexerStrict.STRING_LIT, stringNode.getType());
+           Object value=onLiteral(stringNode, String.class);
+           assertEquals("'Harry*'", value);            
+           rulesTrackerMap.put(ON_IS_LIKE, true);
+       }
+
+       public void onIsNotLike(Tree node, Tree colNode, Tree stringNode) {
+           assertEquals(CMISQLLexerStrict.NOT_LIKE, node.getType());
+           assertEquals(CMISQLLexerStrict.COL, colNode.getType());
+           assertEquals(CMISQLLexerStrict.STRING_LIT, stringNode.getType());
+           Object value=onLiteral(stringNode, String.class);
+           assertEquals("'Harry*'", value);            
+           rulesTrackerMap.put(ON_IS_NOT_LIKE, true);
+       }
+
+       public void onContains(Tree node, Tree colNode, Tree paramNode) {
+           assertEquals(CMISQLLexerStrict.CONTAINS, node.getType());
+           assertTrue(colNode==null || CMISQLLexerStrict.STRING_LIT == paramNode.getType());
+           assertEquals(CMISQLLexerStrict.STRING_LIT, paramNode.getType());
+           rulesTrackerMap.put(ON_CONTAINS, true);
+       }
+
+       public void onInFolder(Tree node, Tree colNode, Tree paramNode) {
+           assertEquals(CMISQLLexerStrict.IN_FOLDER, node.getType());
+           assertTrue(colNode==null || CMISQLLexerStrict.STRING_LIT == paramNode.getType());
+           assertEquals(CMISQLLexerStrict.STRING_LIT, paramNode.getType());
+           rulesTrackerMap.put(ON_IN_FOLDER, true);
+       }
+
+       public void onInTree(Tree node, Tree colNode, Tree paramNode) {
+           assertEquals(CMISQLLexerStrict.IN_TREE, node.getType());
+           assertTrue(colNode==null || CMISQLLexerStrict.STRING_LIT == paramNode.getType());
+           assertEquals(CMISQLLexerStrict.STRING_LIT, paramNode.getType());
+           rulesTrackerMap.put(ON_IN_TREE, true);
+       }
+
+       public void onScore(Tree node, Tree paramNode) {
+           assertEquals(CMISQLLexerStrict.SCORE, node.getType());
+           rulesTrackerMap.put(ON_SCORE, true);
+       }
+
+
+       // private helper functions:
+
+       private boolean isLiteral(Tree node) {
+           int type = node.getType();
+           return type==CMISQLLexerStrict.BOOL_LIT || type==CMISQLLexerStrict.NUM_LIT ||
+           type==CMISQLLexerStrict.STRING_LIT || type==CMISQLLexerStrict.TIME_LIT;
+       }
+
+       private Object onLiteral(Tree node, Class<?> clazz) {
+           int type = node.getType();
+           switch (type) {
+           case CMISQLLexerStrict.BOOL_LIT:
+               return clazz==Boolean.class ? Boolean.parseBoolean(node.getText()) : null;
+           case CMISQLLexerStrict.NUM_LIT:
+               if (clazz == Integer.class)
+                   return Integer.parseInt(node.getText());
+               else if (clazz == Long.class)
+                   return Long.parseLong(node.getText());
+               else if (clazz == Short.class)
+                   return Short.parseShort(node.getText());
+               else if (clazz == Double.class)
+                   return Double.parseDouble(node.getText());
+               else if (clazz == Float.class)
+                   return Float.parseFloat(node.getText());
+               else return null;
+           case CMISQLLexerStrict.STRING_LIT:
+               return clazz==String.class ? node.getText() : null;
+           case CMISQLLexerStrict.TIME_LIT:
+               return clazz==GregorianCalendar.class ?  CalendarHelper.fromString(node.getText()) : null; 
+           default:
+               log.error("Unknown literal. " + node);
+               return null;
+           }
+       }
+
+    }
+
+    private TypeManagerImpl tm;
+    private TestQueryProcessor queryProcessor;
+
+    @Before
+    public void setUp() throws Exception {
+        tm = new TypeManagerImpl();
+        tm.initTypeSystem(null); // create CMIS default types
+
+        // create some types for testing
+        List<TypeDefinition> typeDefs = super.createTypes();
+        for (TypeDefinition typeDef : typeDefs)
+            tm.addTypeDefinition(typeDef);
+
+        // initialize query object with type manager
+        queryProcessor = new TestQueryProcessor();
+        QueryObject qo = new QueryObject(tm, queryProcessor);
+        super.setUp(qo);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    @Test
+    public void testStartStopProcessing() {
+        String statement = "SELECT BookType.Title, BookType.Author FROM BookType WHERE ISBN = 100"; 
+        traverseStatementAndCatchExc(statement); // calls query processor
+        assertTrue(queryProcessor.rulesTrackerMap.get(TestQueryProcessor.ON_START));
+        assertTrue(queryProcessor.rulesTrackerMap.get(TestQueryProcessor.ON_STOP));
+    }
+
+    @Test
+    public void testEq() {
+        String statement = "SELECT BookType.Title, BookType.Author FROM BookType WHERE ISBN = 100"; 
+        testStatement(statement, TestQueryProcessor.ON_EQUALS_WASCALLED);
+    }
+
+    @Test
+    public void testNeq() {
+        String statement = "SELECT BookType.Title, BookType.Author FROM BookType WHERE ISBN <> 100"; 
+        testStatement(statement, TestQueryProcessor.ON_NOT_EQUALS);
+    }
+
+    @Test
+    public void testLt() {
+        String statement = "SELECT BookType.Title, BookType.Author FROM BookType WHERE ISBN < 100"; 
+        testStatement(statement, TestQueryProcessor.ON_LESS_THAN);
+    }
+
+    @Test
+    public void testLteq() {
+        String statement = "SELECT BookType.Title, BookType.Author FROM BookType WHERE ISBN <= 100"; 
+        testStatement(statement, TestQueryProcessor.ON_LESS_OR_EQUALS);
+    }
+
+    @Test
+    public void testGt() {
+        String statement = "SELECT BookType.Title, BookType.Author FROM BookType WHERE ISBN > 100"; 
+        testStatement(statement, TestQueryProcessor.ON_GREATER_THAN);
+    }
+
+    @Test
+    public void testGteq() {
+        String statement = "SELECT BookType.Title, BookType.Author FROM BookType WHERE ISBN >= 100"; 
+        testStatement(statement, TestQueryProcessor.ON_GREATER_OR_EQUALS);
+    }
+
+    @Test
+    public void testNot() {
+        String statement = "SELECT BookType.Title, BookType.Author FROM BookType WHERE NOT ISBN = 100"; 
+        testStatementMultiRule(statement, TestQueryProcessor.ON_NOT);
+    }
+
+    @Test
+    public void testAnd() {
+        String statement = "SELECT BookType.Title, BookType.Author FROM BookType WHERE ISBN = 100 AND Title='Harry'"; 
+        testStatementMultiRule(statement, TestQueryProcessor.ON_AND);
+    }
+
+    @Test
+    public void testOr() {
+        String statement = "SELECT BookType.Title, BookType.Author FROM BookType WHERE ISBN = 100 OR Title='Harry'"; 
+        testStatementMultiRule(statement,TestQueryProcessor.ON_OR);
+    }
+
+    @Test
+    public void testIn() {
+        String statement = "SELECT BookType.Title, BookType.Author FROM BookType WHERE Author IN ('Joe', 'Jim')"; 
+        testStatement(statement, TestQueryProcessor.ON_IN);
+    }
+
+    @Test
+    public void testNotIn() {
+        String statement = "SELECT BookType.Title, BookType.Author FROM BookType WHERE Author NOT IN ('Joe', 'Jim')"; 
+        testStatement(statement, TestQueryProcessor.ON_NOT_IN);
+    }
+
+    @Test
+    public void testEqAny() {
+        String statement = "SELECT BookType.Title, BookType.Author FROM BookType WHERE 'Joe' = ANY Author"; 
+        testStatement(statement, TestQueryProcessor.ON_EQ_ANY);
+    }
+
+    @Test
+    public void testInAny() {
+        String statement = "SELECT BookType.Title, BookType.Author FROM BookType WHERE ANY Author IN ('Joe', 'Jim')"; 
+        testStatement(statement, TestQueryProcessor.ON_IN_ANY);
+    }
+
+    @Test
+    public void testNotInAny() {
+        String statement = "SELECT BookType.Title, BookType.Author FROM BookType WHERE ANY Author NOT IN ('Joe', 'Jim')"; 
+        testStatement(statement, TestQueryProcessor.ON_NOT_IN_ANY);
+    }
+
+    @Test
+    public void testOnIsNullWasCalled() {
+        String statement = "SELECT BookType.Title, BookType.Author FROM BookType WHERE Author IS NULL"; 
+        testStatement(statement, TestQueryProcessor.ON_IS_NULL);        
+    }
+
+    @Test
+    public void testOnIsNotNullWasCalled() {
+        String statement = "SELECT BookType.Title, BookType.Author FROM BookType WHERE Author IS NOT NULL"; 
+        testStatement(statement, TestQueryProcessor.ON_IS_NOT_NULL);        
+    }
+
+    @Test
+    public void testOnLikeWasCalled() {
+        String statement = "SELECT BookType.Title, BookType.Author FROM BookType WHERE Author LIKE 'Harry*'"; 
+        testStatement(statement, TestQueryProcessor.ON_IS_LIKE);        
+    }
+
+    @Test
+    public void testOnNotLikeWasCalled() {
+        String statement = "SELECT BookType.Title, BookType.Author FROM BookType WHERE Author NOT LIKE 'Harry*'"; 
+        testStatement(statement, TestQueryProcessor.ON_IS_NOT_LIKE);        
+    }
+
+    @Test
+    public void testOnContainsWasCalled1() {
+        String statement = "SELECT BookType.Title, BookType.Author FROM BookType WHERE CONTAINS('Hello')"; 
+        testStatement(statement, TestQueryProcessor.ON_CONTAINS);        
+    }
+
+    @Test
+    public void testOnContainsWasCalled2() {
+        String statement = "SELECT BookType.Title, BookType.Author FROM BookType WHERE CONTAINS(BookType, 'Harry')";
+        testStatement(statement, TestQueryProcessor.ON_CONTAINS);        
+    }
+
+    @Test
+    public void testOnInFolderWasCalled1() {
+        String statement = "SELECT BookType.Title, BookType.Author FROM BookType WHERE IN_FOLDER('ID1234')"; 
+        testStatement(statement, TestQueryProcessor.ON_IN_FOLDER);        
+    }
+
+    @Test
+    public void testOnInFolderWasCalled2() {
+        String statement = "SELECT BookType.Title, BookType.Author FROM BookType WHERE IN_FOLDER(BookType, 'ID1234')";
+        testStatement(statement, TestQueryProcessor.ON_IN_FOLDER);        
+    }
+
+    @Test
+    public void testOnInTreeWasCalled1() {
+        String statement = "SELECT BookType.Title, BookType.Author FROM BookType WHERE IN_Tree('ID1234')"; 
+        testStatement(statement, TestQueryProcessor.ON_IN_TREE);        
+    }
+
+    @Test
+    public void testOnInTreeWasCalled2() {
+        String statement = "SELECT BookType.Title, BookType.Author FROM BookType WHERE IN_Tree(BookType, 'ID1234')"; 
+        testStatement(statement, TestQueryProcessor.ON_IN_TREE);        
+    }
+
+    @Test
+    public void testOnScoreCalled() {
+        String statement = "SELECT BookType.Title, BookType.Author FROM BookType WHERE SCORE()=100"; 
+        testStatementMultiRule(statement, TestQueryProcessor.ON_SCORE);        
+    }
+
+    // private helper functions
+
+    private void testStatementMultiRule(String statement, String ruleAssertion) {
+        traverseStatementAndCatchExc(statement); // calls query processor
+        Tree whereRoot = getWhereTree(parserTree);
+        assertTrue(queryProcessor.rulesTrackerMap.get(ruleAssertion));
+    }
+
+    private void testStatement(String statement, String ruleAssertion) {
+        testStatementMultiRule(statement, ruleAssertion);
+        checkOtherRulesNotCalled(ruleAssertion);
+    }
+
+    private void checkOtherRulesNotCalled(String ruleAssertion) {
+        for (Entry<String, Boolean> e : queryProcessor.rulesTrackerMap.entrySet()) {
+            if (!e.getKey().equals(ruleAssertion) && !e.getKey().equals("onPropertyValueWasCalled")
+                    && !e.getKey().equals(TestQueryProcessor.ON_START) && !e.getKey().equals(TestQueryProcessor.ON_STOP)
+                    && !e.getKey().contains("Literal"))
+                assertFalse("Rule " + e.getKey() + " was expected not to be executed, but was executed.", 
+                        queryProcessor.rulesTrackerMap.get(e.getKey()));
+        }
+    }
+
+}

Added: incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/test/java/org/apache/chemistry/opencmis/inmemory/query/QueryParseTest.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/test/java/org/apache/chemistry/opencmis/inmemory/query/QueryParseTest.java?rev=954587&view=auto
==============================================================================
--- incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/test/java/org/apache/chemistry/opencmis/inmemory/query/QueryParseTest.java (added)
+++ incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/test/java/org/apache/chemistry/opencmis/inmemory/query/QueryParseTest.java Mon Jun 14 18:51:24 2010
@@ -0,0 +1,825 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.chemistry.opencmis.inmemory.query;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.List;
+import java.util.Map;
+
+import org.antlr.runtime.MismatchedTokenException;
+import org.antlr.runtime.RecognitionException;
+import org.antlr.runtime.tree.CommonTree;
+import org.antlr.runtime.tree.Tree;
+import org.apache.chemistry.opencmis.inmemory.query.QueryObject.SortSpec;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class QueryParseTest extends AbstractQueryTest {
+
+    private static Log LOG = LogFactory.getLog(QueryParseTest.class);
+
+    @Before
+    public void setUp() throws Exception {
+        // initialize query object, we do not need a type manager for just testing parsing
+        super.setUp(new QueryObject(null, null));
+    }
+    
+    @After
+    public void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    @Test
+    public void simpleSelectTest1() throws Exception {
+        String statement = "SELECT SCORE() FROM cmis:document"; 
+        
+        CmisQueryWalker walker = traverseStatementAndCatchExc(statement);
+        QueryObject select = walker.queryObj;
+        List<CmisSelector> selects = select.getSelectReferences();
+        assertTrue(1 == selects.size());
+        assertTrue(selects.get(0) instanceof FunctionReference);
+        FunctionReference funcRef = ((FunctionReference)selects.get(0));
+        assertTrue(FunctionReference.CmisQlFunction.SCORE == funcRef.getFunction());
+    }
+    
+    @Test
+    public void simpleSelectTest2() throws Exception {
+        String statement = "SELECT abc FROM cmis:document";         
+        CmisQueryWalker walker = traverseStatementAndCatchExc(statement);
+        QueryObject select = walker.queryObj;
+        List<CmisSelector> selects = queryObj.getSelectReferences();
+        assertTrue(1 == selects.size());
+        // nothing should be in where references
+        assertTrue(0 == select.getWhereReferences().size());
+
+        ColumnReference colRef = ((ColumnReference)selects.get(0));
+        assertTrue(selects.get(0) instanceof ColumnReference);
+        assertEquals("abc", colRef.getPropertyQueryName());
+        
+    }
+    
+    @Test
+    public void simpleSelectTest3() throws Exception {
+        String statement = "SELECT t1.abc FROM cmis:document";        
+        CmisQueryWalker walker = traverseStatementAndCatchExc(statement);
+        QueryObject select = walker.queryObj;
+        List<CmisSelector> selects = select.getSelectReferences();
+        assertTrue(1 == selects.size());
+        // nothing should be in where references
+        assertTrue(0 == select.getWhereReferences().size());
+        assertTrue(selects.get(0) instanceof ColumnReference);
+        ColumnReference colRef = ((ColumnReference)selects.get(0));
+        assertEquals("t1", colRef.getTypeQueryName());
+        assertEquals("abc", colRef.getPropertyQueryName());
+
+    }
+    
+    @Test
+    public void simpleSelectTest4() throws Exception {
+        String statement = "SELECT * FROM cmis:document";        
+        CmisQueryWalker walker = traverseStatementAndCatchExc(statement);
+        QueryObject select = walker.queryObj;
+        List<CmisSelector> selects = select.getSelectReferences();
+        assertTrue(1 == selects.size());
+        // nothing should be in where references
+        assertTrue(0 == select.getWhereReferences().size());
+        ColumnReference colRef = ((ColumnReference)selects.get(0));
+        assertTrue(selects.get(0) instanceof ColumnReference);
+        assertEquals(null, colRef.getTypeQueryName());
+        assertEquals("*", colRef.getPropertyQueryName());
+
+        
+    }
+    
+    @Test
+    public void simpleSelectTest5() throws Exception {
+        String statement = "SELECT t1.* FROM cmis:document";        
+        CmisQueryWalker walker = traverseStatementAndCatchExc(statement);
+        QueryObject select = walker.queryObj;
+        List<CmisSelector> selects = select.getSelectReferences();
+        assertTrue(1 == selects.size());
+        // nothing should be in where references
+        assertTrue(0 == select.getWhereReferences().size());
+        assertTrue(selects.get(0) instanceof ColumnReference);
+        ColumnReference colRef = ((ColumnReference)selects.get(0));
+        assertEquals("t1", colRef.getTypeQueryName());
+        assertEquals("*", colRef.getPropertyQueryName());
+        
+    }
+    
+    @Test
+    public void simpleSelectTest6() throws Exception {
+        String statement = "SELECT t2.aaa myalias FROM cmis:document";        
+        CmisQueryWalker walker = traverseStatementAndCatchExc(statement);
+        QueryObject select = walker.queryObj;
+        List<CmisSelector> selects = select.getSelectReferences();
+        assertTrue(1 == selects.size());
+        // nothing should be in where references
+        assertTrue(0 == select.getWhereReferences().size());
+        assertTrue(selects.get(0) instanceof ColumnReference);
+        ColumnReference colRef = ((ColumnReference)selects.get(0));
+        assertEquals("t2", colRef.getTypeQueryName());
+        assertEquals("aaa", colRef.getPropertyQueryName());
+
+    }
+    
+    @Test
+    public void simpleSelectTest7() throws Exception {
+        // error processing
+        String statement = "SELECTXXX t2.aaa myalias FROM cmis:document WHERE a < t1";        
+        try {
+            CmisQueryWalker walker = traverseStatement(statement);
+            fail("Walking of statement should with RecognitionException but succeeded"); 
+        } catch (Exception e) {
+            assertTrue(e instanceof RecognitionException || e instanceof MismatchedTokenException);
+        }
+
+    }
+    
+    @Test
+    public void simpleFromTest1() throws Exception {
+        String statement = "SELECT * FROM MyType MyAlias"; 
+        
+        CmisQueryWalker walker = traverseStatementAndCatchExc(statement);
+        QueryObject from = walker.queryObj;
+        Map<String,String> types = from.getTypes();
+        assertTrue(1 == types.size());
+        String key = types.keySet().iterator().next();
+        assertEquals("MyAlias", key);
+        assertEquals("MyType", types.get(key));
+    }
+    
+    @Test
+    public void simpleFromTest2() throws Exception {
+        String statement = "SELECT * FROM MyType";        
+        CmisQueryWalker walker = traverseStatementAndCatchExc(statement);
+        QueryObject from = walker.queryObj;
+        Map<String,String> types = from.getTypes();
+        assertTrue(1 == types.size());
+        String key = types.keySet().iterator().next();
+        assertEquals("MyType", key);
+        assertEquals("MyType", types.get(key));
+    
+    }
+    
+    @Test
+    public void simpleFromTest3() throws Exception {
+        String statement = "SELECT t2.aaa FROM MyType abc123";        
+        CmisQueryWalker walker = traverseStatementAndCatchExc(statement);
+        QueryObject from = walker.queryObj;
+        Map<String,String> types = from.getTypes();
+        assertTrue(1 == types.size());
+        String key = types.keySet().iterator().next();
+        assertEquals("abc123", key);
+        assertEquals("MyType", types.get(key));
+    }
+    
+    @Test
+    public void simpleWhereTest() throws Exception {
+        String statement = "SELECT * FROM MyType WHERE MyProp1=123"; 
+        
+        CmisQueryWalker walker = traverseStatementAndCatchExc(statement);
+        QueryObject qo = walker.queryObj;
+        List<CmisSelector> whereRefs = qo.getWhereReferences();
+        Map<Integer, CmisSelector> colRefs = qo.getColumnReferences();
+        assertTrue(1 == whereRefs.size());
+        CmisSelector value = whereRefs.iterator().next();
+        assertTrue(value instanceof ColumnReference);
+        assertEquals("MyProp1", ((ColumnReference)value).getPropertyQueryName());
+        // only "*" should be in select references
+        assertTrue(1 == qo.getSelectReferences().size());
+
+        CommonTree tree = (CommonTree) walker.getTreeNodeStream().getTreeSource();
+        
+        // System.out.println("simpleWhereTest printing Tree ...");
+        // System.out.println("id in map: " + System.identityHashCode(whereRefs.keySet().iterator().next()));
+//        assertTrue(traverseTreeAndFindNodeInColumnMap(tree, colRefs));
+        traverseTreeAndFindNodeInColumnMap2(tree, colRefs);
+        // System.out.println("... simpleWhereTest printing Tree done.");
+    }
+    
+    // check if the map containing all column references in the where clause has an existing node as key
+    private boolean traverseTreeAndFindNodeInColumnMap(Tree node, Map<Object, CmisSelector> colRefs) {
+        boolean found = false;
+//        System.out.println("cmp to: " + System.identityHashCode(node) + " is: " + node.toString());
+        if (null != colRefs.get(node))
+            return true;
+        
+        int count = node.getChildCount();
+        for (int i=0; i<count && !found; i++) {
+            Tree child = node.getChild(i);
+            found = traverseTreeAndFindNodeInColumnMap(child, colRefs);
+        }
+        return found;
+    }
+
+    // check if the map containing all column references in the where clause has an existing node as key
+    private void traverseTreeAndFindNodeInColumnMap2(Tree node, Map<Object, CmisSelector> colRefs) {
+        for (Object obj : colRefs.keySet()){
+            LOG.debug("find object: " + obj + " identity hash code: " + System.identityHashCode(obj));
+            assertTrue(traverseTreeAndFindNodeInColumnMap2(node, obj));
+        }
+    }
+
+    private boolean traverseTreeAndFindNodeInColumnMap2(Tree node, Object colRef) {
+        int count = node.getChildCount();
+        LOG.debug("  checking with: " + node + " identity hash code: " + System.identityHashCode(node));
+        if (node==colRef)
+            return true;
+        boolean found = false;
+        for (int i=0; i<count && !found; i++) {
+            Tree child = node.getChild(i);
+            found = traverseTreeAndFindNodeInColumnMap2(child, colRef);
+        }
+        return found;
+    }
+    
+    @Test
+    public void simpleSortTest1() throws Exception {
+        String statement = "SELECT * FROM MyType ORDER BY abc.def ASC"; 
+        
+        CmisQueryWalker walker = traverseStatementAndCatchExc(statement);
+        List<SortSpec> orderBys = walker.queryObj.getOrderBys();
+        assertTrue(1 == orderBys.size());
+        SortSpec sp = orderBys.get(0);
+        assertTrue(sp.isAscending());
+        CmisSelector sortSpec = sp.getSelector();
+        assert(sortSpec instanceof ColumnReference);
+        assertEquals("abc", ((ColumnReference)sortSpec).getTypeQueryName());
+        assertEquals("def", ((ColumnReference)sortSpec).getPropertyQueryName());
+    }
+    
+    @Test
+    public void simpleSortTest2() throws Exception {
+        String statement = "SELECT * FROM MyType ORDER BY def DESC";        
+        CmisQueryWalker walker = traverseStatementAndCatchExc(statement);
+        List<SortSpec> orderBys = walker.queryObj.getOrderBys();
+        assertTrue(1 == orderBys.size());
+        SortSpec sp = orderBys.get(0);
+        assertFalse(sp.isAscending());
+        CmisSelector sortSpec = sp.getSelector();
+        assert(sortSpec instanceof ColumnReference);
+        assertNull(((ColumnReference)sortSpec).getTypeQueryName());
+        assertEquals("def", ((ColumnReference)sortSpec).getPropertyQueryName());
+    }
+    
+    @Test
+    public void printTreeTest() {
+        System.out.println("printTreeTest():");        
+        String statement = "SELECT p1, p2, p3.t3 mycol FROM MyType AS MyAlias WHERE p1='abc' and p2=123 ORDER BY abc.def ASC";         
+        try {
+            getWalker(statement);
+            printTree(parserTree, statement);
+            
+        } catch (Exception e) {
+            fail("Cannot parse query: " + statement + " (" + e + ")");
+        }
+    }
+
+    @Test
+    public void extractWhereTreeTest() {
+        System.out.println("extractWhereTreeTest():");
+        String statement = "SELECT p1, p2, p3.t3 mycol FROM MyType AS MyAlias WHERE p1='abc' and p2=123 ORDER BY abc.def ASC"; 
+        
+        try {
+            getWalker(statement);
+            Tree whereTree = getWhereTree(parserTree);
+            printTree(whereTree);
+            System.out.println("Evaluate WHERE subtree: ...");
+            evalWhereTree(whereTree);
+            
+        } catch (Exception e) {
+            fail("Cannot parse query: " + statement + " (" + e + ")");
+        }
+    }
+    
+    @Test
+    public void whereTestIn() {
+        System.out.println("extractWhereTestIN():");
+        String statement = "SELECT p1 FROM MyType WHERE p1 IN ('Red', 'Green', 'Blue', 'Black')"; 
+        checkTreeWhere(statement);
+    }
+    
+    @Test
+    public void whereTestEq() {
+      String statement = "SELECT p1 FROM MyType WHERE p1='abc'";
+      checkTreeWhere(statement);
+    }
+
+    @Test
+    public void whereTestNotEq() {
+      String statement = "SELECT p1 FROM MyType WHERE p1 <> 123";
+      checkTreeWhere(statement);
+    }
+
+    @Test
+    public void whereTestLT() {
+      String statement = "SELECT p1 FROM MyType WHERE p1 < 123";
+      checkTreeWhere(statement);
+    }
+
+    @Test
+    public void whereTestGT() {
+      String statement = "SELECT p1 FROM MyType WHERE p1 > 123";
+      checkTreeWhere(statement);
+    }
+
+    @Test
+    public void whereTestLTEQ() {
+      String statement = "SELECT p1 FROM MyType WHERE p1 <= 123";
+      checkTreeWhere(statement);
+    }
+
+    @Test
+    public void whereTestGTEQ() {
+      String statement = "SELECT p1 FROM MyType WHERE p1 >= 123";
+      checkTreeWhere(statement);
+    }
+
+    @Test
+    public void whereTestAnd() {
+      String statement = "SELECT p1 FROM MyType WHERE p1=1 AND p2=2";
+      checkTreeWhere(statement);
+    }
+
+    @Test
+    public void whereTestOr() {
+      String statement = "SELECT p1 FROM MyType WHERE p1='abc' OR p2=123";
+      checkTreeWhere(statement);
+    }
+
+    @Test
+    public void whereTestNot() {
+      String statement = "SELECT p1 FROM MyType WHERE NOT p1 = 123";
+      checkTreeWhere(statement);
+    }
+
+    @Test
+    public void whereTestInFolder() {
+      String statement = "SELECT p1 FROM MyType WHERE IN_FOLDER('myfolder')";
+      checkTreeWhere(statement);
+    }
+    
+    @Test
+    public void whereTestInTree() {
+      String statement = "SELECT p1 FROM MyType WHERE IN_TREE('myfolder')";
+      checkTreeWhere(statement);
+    }
+        
+    @Test
+    public void whereTestAny() {
+      String statement = "SELECT p1 FROM MyType WHERE 'Smith' = ANY Authors "; 
+      checkTreeWhere(statement);
+    }
+
+    
+    @Test
+    public void whereTestAnyIn() {
+      String statement = "SELECT p1 FROM MyType WHERE ANY Colors IN ('Red', 'Green', 'Blue')"; 
+      checkTreeWhere(statement);
+    }
+    
+    @Test
+    public void whereTestLike() {
+      String statement = "SELECT p1 FROM MyType WHERE p1 LIKE 'abc*' "; 
+      checkTreeWhere(statement);
+    }
+
+    @Test
+    public void whereTestNotLike() {
+      String statement = "SELECT p1 FROM MyType WHERE p1 NOT LIKE 'abc*'";
+      checkTreeWhere(statement);
+    }
+    
+    @Test
+    public void whereTestNull() {
+      String statement = "SELECT p1 FROM MyType WHERE p1 IS NULL";
+      checkTreeWhere(statement);
+    }
+
+    @Test
+    public void whereTestNotNull() {
+      String statement = "SELECT p1 FROM MyType WHERE p1 IS NOT NULL";
+      checkTreeWhere(statement);
+    }
+    
+    @Test
+    public void whereTestContains() {
+      String statement = "SELECT p1 FROM MyType WHERE CONTAINS('Beethoven')";
+      checkTreeWhere(statement);
+    }
+
+    @Test
+    public void whereTestScore() {
+      String statement = "SELECT p1 FROM MyType WHERE SCORE() = 100";
+      checkTreeWhere(statement);
+    }
+
+    @Test
+    public void whereTestParentheses() {
+      String statement = "SELECT p1 FROM MyType WHERE (p1 IS NULL OR SCORE()=100) AND (p2=123 OR p3=456)";
+      checkTreeWhere(statement);
+    }
+
+    @Test
+    public void doubleFromTest() throws Exception {
+        String statement = "SELECT * FROM MyType JOIN YourType WHERE a='1'"; 
+        
+        CmisQueryWalker walker = traverseStatementAndCatchExc(statement);
+        QueryObject from = walker.queryObj;
+        Map<String,String> types = from.getTypes();
+        assertTrue(2 == types.size());
+    }
+    
+    @Test
+    public void duplicatedAliasTestSelect() throws Exception {
+        String statement = "SELECT p1.T1 MyAlias, p2.T1 AS MyAlias FROM T1";
+        try {
+            traverseStatement(statement);            
+        } catch (Exception e) {
+            assertTrue(e.getMessage().contains("more than once as alias in a select"));
+        }
+    }
+
+    @Test
+    public void duplicatedAliasTestFrom() throws Exception {
+        String statement = "SELECT * FROM T1 MyAlias JOIN T2 AS MyAlias";
+        try {
+            traverseStatement(statement);            
+        } catch (Exception e) {
+            assertTrue(e.getMessage().contains("more than once as alias in a from"));
+        }
+    }
+    
+    private void checkTreeWhere(String statement) {
+        System.out.println();
+        System.out.println("checkTreeWhere: " + statement);
+        traverseStatementAndCatchExc(statement);
+        Tree whereTree = getWhereTree(walkerTree);
+        evalWhereTree(whereTree);
+    }
+
+    private void evalWhereTree(Tree root) {
+        int count = root.getChildCount();
+        for (int i=0; i<count; i++) {
+            Tree child = root.getChild(i);
+            evaluateWhereNode(child);
+            evalWhereTree(child); // recursive descent
+        }
+    }
+
+    private void printTree(Tree tree, String statement) {
+        System.out.println("Printing the abstract syntax tree for statement:");
+        System.out.println("  " + statement);
+        printTree(tree);
+    }
+    
+    private int indent = 1;
+
+    private String indentString() {
+        StringBuffer sb = new StringBuffer();
+        for (int i = 0; i < indent; ++i) {
+            sb.append("  ");
+        }
+        return sb.toString();
+    }
+
+    private void printTree(Tree node) {
+        System.out.println(indentString() + printNode(node));
+        ++indent;
+        int count = node.getChildCount();
+        for (int i=0;i<count;i++) {
+            Tree child = node.getChild(i);
+            printTree(child);
+        }
+        --indent;     
+    } 
+       
+    private String printNode(Tree node) {
+        switch (node.getType()) {
+        case CMISQLLexerStrict.TABLE:
+            return "#TABLE";
+        case CMISQLLexerStrict.COL:
+            return "#COL";
+        case CMISQLLexerStrict.IN_LIST:
+            return "#IN_LIST";
+        case CMISQLLexerStrict.SEL_LIST:
+            return "#SEL_LIST";
+        case CMISQLLexerStrict.EQ_ANY:
+            return "#EQ_ANY";
+        case CMISQLLexerStrict.NOT_LIKE:
+            return "#NOT_LIKE";
+        case CMISQLLexerStrict.NOT_IN:
+            return "#NOT_IN";
+        case CMISQLLexerStrict.IN_ANY:
+            return "#IN_ANY";
+        case CMISQLLexerStrict.NOT_IN_ANY:
+            return "#NOT_IN_ANY";
+        case CMISQLLexerStrict.IS_NULL:
+            return "#IS_NULL";
+        case CMISQLLexerStrict.IS_NOT_NULL:
+            return "#IS_NOT_NULL";
+        case CMISQLLexerStrict.ORDER_BY:
+            return "#ORDER_BY";
+          
+        case CMISQLLexerStrict.WHERE:;
+        case CMISQLLexerStrict.LT:
+        case CMISQLLexerStrict.STAR:
+        case CMISQLLexerStrict.BOOL_LIT:
+        case CMISQLLexerStrict.INNER:
+        case CMISQLLexerStrict.TIME_LIT:
+        case CMISQLLexerStrict.ORDER:
+        case CMISQLLexerStrict.STRING_LIT:
+        case CMISQLLexerStrict.CONTAINS:
+        case CMISQLLexerStrict.ExactNumLit:
+        case CMISQLLexerStrict.LTEQ:
+        case CMISQLLexerStrict.NOT:
+        case CMISQLLexerStrict.ID:
+        case CMISQLLexerStrict.AND:
+        case CMISQLLexerStrict.EOF:
+        case CMISQLLexerStrict.AS:
+        case CMISQLLexerStrict.IN:
+        case CMISQLLexerStrict.LPAR:
+        case CMISQLLexerStrict.Digits:
+        case CMISQLLexerStrict.COMMA:
+        case CMISQLLexerStrict.IS:
+        case CMISQLLexerStrict.LEFT:
+        case CMISQLLexerStrict.Sign:
+        case CMISQLLexerStrict.EQ:
+        case CMISQLLexerStrict.DOT:
+        case CMISQLLexerStrict.NUM_LIT:
+        case CMISQLLexerStrict.SELECT:
+        case CMISQLLexerStrict.LIKE:
+        case CMISQLLexerStrict.OUTER:
+        case CMISQLLexerStrict.BY:
+        case CMISQLLexerStrict.ASC:
+        case CMISQLLexerStrict.NULL:
+        case CMISQLLexerStrict.ON:
+        case CMISQLLexerStrict.RIGHT:
+        case CMISQLLexerStrict.GTEQ:
+        case CMISQLLexerStrict.ApproxNumLit:
+        case CMISQLLexerStrict.JOIN:
+        case CMISQLLexerStrict.IN_FOLDER:
+        case CMISQLLexerStrict.WS:
+        case CMISQLLexerStrict.NEQ:
+        case CMISQLLexerStrict.ANY:
+        case CMISQLLexerStrict.SCORE:
+        case CMISQLLexerStrict.IN_TREE:
+        case CMISQLLexerStrict.OR:
+        case CMISQLLexerStrict.GT:
+        case CMISQLLexerStrict.RPAR:
+        case CMISQLLexerStrict.DESC:
+        case CMISQLLexerStrict.FROM:
+        case CMISQLLexerStrict.TIMESTAMP:
+            return node.toString();
+        default:
+            return "[Unknown token: " + node.toString() + "]";
+        }
+    }
+    
+    
+    // Ensure that we receive only valid tokens and nodes in the where clause:
+    private void evaluateWhereNode(Tree node) {
+        System.out.println("evaluating node: " + node.toString());
+        switch (node.getType()) {
+        case CMISQLLexerStrict.WHERE:;
+            break; // ignore
+        case CMISQLLexerStrict.COL:
+            evalColumn(node);
+        case CMISQLLexerStrict.IN_LIST:
+            evalInList(node);
+            break;
+        case CMISQLLexerStrict.IN_ANY:
+            evalInAny(node);
+            break;
+        case CMISQLLexerStrict.EQ_ANY:
+            evalEqAny(node);
+            break;
+        case CMISQLLexerStrict.NOT_LIKE:
+            evalNotLike(node);
+            break;
+        case CMISQLLexerStrict.NOT_IN:
+            evalNotIn(node);
+            break;
+        case CMISQLLexerStrict.IS_NULL:
+            evalIsNull(node);
+            break;
+        case CMISQLLexerStrict.IS_NOT_NULL:
+            evalIsNotNull(node);
+            break;
+        case CMISQLLexerStrict.LT:
+            evalLessThan(node);
+            break;
+        case CMISQLLexerStrict.BOOL_LIT:
+            evalBooleanLiteral(node);
+            break;
+        case CMISQLLexerStrict.TIME_LIT:
+            evalTimeLiteral(node);
+            break;
+        case CMISQLLexerStrict.STRING_LIT:
+            evalStringLiteral(node);
+            break;
+        case CMISQLLexerStrict.CONTAINS:
+            evalContains(node);
+            break;
+        case CMISQLLexerStrict.ExactNumLit:
+            evalExactNumLiteral(node);
+            break;
+        case CMISQLLexerStrict.LTEQ:
+            evalLessOrEqual(node);
+            break;
+        case CMISQLLexerStrict.NOT:
+            evalNot(node);
+            break;
+        case CMISQLLexerStrict.ID:
+            evalId(node);
+            break;
+        case CMISQLLexerStrict.AND:
+            evalAnd(node);
+            break;
+        case CMISQLLexerStrict.IN:
+            evalIn(node);
+            break;
+        case CMISQLLexerStrict.EQ:
+            evalEquals(node);
+            break;
+        case CMISQLLexerStrict.NUM_LIT:
+            evalNumLiteral(node);
+            break;
+        case CMISQLLexerStrict.LIKE:
+            evalLike(node);
+            break;
+        case CMISQLLexerStrict.NULL:
+            evalNull(node);
+            break;
+        case CMISQLLexerStrict.GTEQ:
+            evalGreaterThan(node);
+            break;
+        case CMISQLLexerStrict.ApproxNumLit:
+            evalApproxNumLiteral(node);
+            break;
+        case CMISQLLexerStrict.IN_FOLDER:
+            evalInFolder(node);
+            break;
+        case CMISQLLexerStrict.NEQ:
+            evalNotEquals(node);
+            break;
+        case CMISQLLexerStrict.SCORE:
+            evalScore(node);
+            break;
+        case CMISQLLexerStrict.IN_TREE:
+            evalInTree(node);
+            break;
+        case CMISQLLexerStrict.OR:
+            evalOr(node);
+            break;
+        case CMISQLLexerStrict.GT:
+            evalGreaterThan(node);
+            break;
+        case CMISQLLexerStrict.TIMESTAMP:
+            evalTimeLiteral(node);
+            break;
+        default:
+            fail("[Unexpected node in WHERE clause: " + node.toString() + "]");
+        }
+    }
+
+    private void evalInAny(Tree node) {
+    }
+
+    private void evalColumn(Tree node) {
+        assertEquals(1, node.getChildCount());
+        assertEquals(CMISQLLexerStrict.ID, node.getChild(0).getType());
+    }
+
+    private void evalEquals(Tree node) {
+        assertEquals(2, node.getChildCount());
+    }
+
+    private void evalInFolder(Tree node) {
+        assertEquals(1, node.getChildCount());
+    }
+
+    private void evalApproxNumLiteral(Tree node) {
+    }
+
+    private void evalNull(Tree node) {
+        assertEquals(1, node.getChildCount());
+    }
+
+    private void evalLike(Tree node) {
+        assertEquals(2, node.getChildCount());
+    }
+
+    private void evalNumLiteral(Tree node) {
+        assertEquals(0, node.getChildCount());
+    }
+
+    private void evalInList(Tree node) {
+    }
+
+    private void evalEqAny(Tree node) {
+    }
+
+    private void evalNotLike(Tree node) {
+        assertEquals(2, node.getChildCount());
+    }
+
+    private void evalNotIn(Tree node) {
+    }
+
+    private void evalIsNull(Tree node) {
+        assertEquals(1, node.getChildCount());
+    }
+
+    private void evalIsNotNull(Tree node) {
+        assertEquals(1, node.getChildCount());
+    }
+
+    private void evalLessThan(Tree node) {
+        assertEquals(2, node.getChildCount());
+    }
+
+    private void evalBooleanLiteral(Tree node) {
+        assertEquals(0, node.getChildCount());
+    }
+
+    private void evalStringLiteral(Tree node) {
+        assertEquals(0, node.getChildCount());
+    }
+
+    private void evalContains(Tree node) {
+        assertEquals(1, node.getChildCount());
+    }
+
+    private void evalExactNumLiteral(Tree node) {
+        assertEquals(0, node.getChildCount());
+    }
+
+    private void evalLessOrEqual(Tree node) {
+        assertEquals(2, node.getChildCount());
+    }
+
+    private void evalNot(Tree node) {
+        assertEquals(1, node.getChildCount());
+    }
+
+    private void evalId(Tree node) {
+        assertEquals(0, node.getChildCount());
+    }
+
+    private void evalAnd(Tree node) {
+        assertEquals(2, node.getChildCount());
+    }
+
+    private void evalIn(Tree node) {
+    }
+
+    private void evalNotEquals(Tree node) {
+        assertEquals(2, node.getChildCount());
+    }
+
+    private void evalScore(Tree node) {
+        assertEquals(0, node.getChildCount());
+    }
+
+    private void evalInTree(Tree node) {
+        assertEquals(1, node.getChildCount());
+    }
+
+    private void evalOr(Tree node) {
+        assertEquals(2, node.getChildCount());
+    }
+
+    private void evalGreaterThan(Tree node) {
+        assertEquals(2, node.getChildCount());
+    }
+
+    private void evalTimeLiteral(Tree node) {
+        assertEquals(0, node.getChildCount());
+    }
+}