Return-Path: Delivered-To: apmail-incubator-chemistry-commits-archive@minotaur.apache.org Received: (qmail 21808 invoked from network); 12 Jul 2010 06:43:22 -0000 Received: from unknown (HELO mail.apache.org) (140.211.11.3) by 140.211.11.9 with SMTP; 12 Jul 2010 06:43:22 -0000 Received: (qmail 51147 invoked by uid 500); 12 Jul 2010 06:43:21 -0000 Delivered-To: apmail-incubator-chemistry-commits-archive@incubator.apache.org Received: (qmail 51102 invoked by uid 500); 12 Jul 2010 06:43:20 -0000 Mailing-List: contact chemistry-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: chemistry-dev@incubator.apache.org Delivered-To: mailing list chemistry-commits@incubator.apache.org Received: (qmail 51089 invoked by uid 99); 12 Jul 2010 06:43:20 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 12 Jul 2010 06:43:20 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 12 Jul 2010 06:43:15 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 37F102388A1C; Mon, 12 Jul 2010 06:41:51 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r963193 [3/3] - in /incubator/chemistry/opencmis/trunk/chemistry-opencmis-server: chemistry-opencmis-server-inmemory/ chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/ chemistry-opencmis-server-inmemor... Date: Mon, 12 Jul 2010 06:41:50 -0000 To: chemistry-commits@incubator.apache.org From: jens@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20100712064151.37F102388A1C@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Added: incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-support/src/test/java/org/apache/chemistry/opencmis/server/support/query/AbstractParserTst.java URL: http://svn.apache.org/viewvc/incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-support/src/test/java/org/apache/chemistry/opencmis/server/support/query/AbstractParserTst.java?rev=963193&view=auto ============================================================================== --- incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-support/src/test/java/org/apache/chemistry/opencmis/server/support/query/AbstractParserTst.java (added) +++ incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-support/src/test/java/org/apache/chemistry/opencmis/server/support/query/AbstractParserTst.java Mon Jul 12 06:41:49 2010 @@ -0,0 +1,196 @@ +/* + * 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.server.support.query; + +import static org.junit.Assert.fail; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; + +import org.antlr.runtime.ANTLRStringStream; +import org.antlr.runtime.CharStream; +import org.antlr.runtime.CommonTokenStream; +import org.antlr.runtime.Lexer; +import org.antlr.runtime.TokenStream; +import org.antlr.runtime.tree.CommonTree; +import org.antlr.stringtemplate.StringTemplate; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * This class is clone of org.antlr.gunit.gUnitBase class adapted to Java style + * Because the original class can't deal with composite grammar this is a replacement + * working around this antlr bug. + * + */ +public class AbstractParserTst{ + + private static Log log = LogFactory.getLog(AbstractParserTst.class); + + protected String superGrammarName; + Class lexer; + Class parser; + protected String treeParserPath; + + protected void setUp(Class lexerClass, Class parserClass, String baseGrammar) throws Exception { + lexer = lexerClass; + parser = parserClass; + this.superGrammarName = baseGrammar; + } + + protected void tearDown() throws Exception { + } + + protected void testLexerOk(String rule, String statement) throws Exception { + // test input: "a" + try { + Object retval = execLexer(rule, statement, false); + log.debug("testing rule " + rule + " parsed to: " + retval); + } catch (Exception e) { + fail("testing rule " + rule + ": " + e.toString()); + } + } + + protected void testLexerFail(String rule, String statement) throws Exception { + // test input: "a" + try { + Object retval = execLexer(rule, statement, false); + fail("testing rule should fail " + rule); + } catch (Exception e) { + log.debug("testing rule " + rule + " parsed with exception: " + e); + } + } + + protected void testParserOk(String rule, String statement) throws Exception { + try { + Object retval = execParser(rule, statement, false); + log.debug("testing rule " + rule + " parsed to: " + retval); + } catch (Exception e) { + fail("testing rule "+rule + " failed: " + e.toString()); + } + } + + protected void testParserFail(String rule, String statement) throws Exception { + try { + Object retval = execParser(rule, statement, false); + fail("testing rule should fail " + rule); + } catch (Exception e) { + log.debug("testing rule "+rule + " failed: " + e.toString()); + } + } + + protected void testParser(String rule, String statement, String expectedResult) throws Exception { + try { + Object actual = execParser(rule, statement, false); + log.debug("testing rule " + rule + " parsed to: " + actual); + } catch (Exception e) { + fail("testing rule " + rule + " failed: " + e); + } + } + + + // Invoke target lexer.rule + public String execLexer(String testRuleName, String testInput, boolean isFile) throws Exception { + String result = null; + CharStream input; + /** Set up ANTLR input stream based on input source, file or String */ + input = new ANTLRStringStream(testInput); + + /** Use Reflection to create instances of lexer and parser */ + Class[] lexArgTypes = new Class[]{CharStream.class}; // assign type to lexer's args + Constructor lexConstructor = lexer.getConstructor(lexArgTypes); + Object[] lexArgs = new Object[]{input}; // assign value to lexer's args + Object lexObj = lexConstructor.newInstance(lexArgs); // makes new instance of lexer + + Method ruleName = lexer.getMethod("m"+testRuleName, new Class[0]); + + /** Invoke lexer rule, and get the current index in CharStream */ + ruleName.invoke(lexObj, new Object[0]); + Method ruleName2 = lexer.getMethod("getCharIndex", new Class[0]); + int currentIndex = (Integer) ruleName2.invoke(lexObj, new Object[0]); + if ( currentIndex!=input.size() ) { + throw new RuntimeException("extra text found, '"+input.substring(currentIndex, input.size()-1)+"'"); +// System.out.println("extra text found, '"+input.substring(currentIndex, input.size()-1)+"'"); + } + + return result; + } + + // Invoke target parser.rule + public Object execParser(String testRuleName, String testInput, boolean isFile) throws Exception { + String result = null; + CharStream input; + /** Set up ANTLR input stream based on input source, file or String */ + input = new ANTLRStringStream(testInput); + + /** Use Reflection to create instances of lexer and parser */ + Class[] lexArgTypes = new Class[]{CharStream.class}; // assign type to lexer's args + Constructor lexConstructor = lexer.getConstructor(lexArgTypes); + Object[] lexArgs = new Object[]{input}; // assign value to lexer's args + Object lexObj = lexConstructor.newInstance(lexArgs); // makes new instance of lexer + + CommonTokenStream tokens = new CommonTokenStream((Lexer) lexObj); + Class[] parArgTypes = new Class[]{TokenStream.class}; // assign type to parser's args + Constructor parConstructor = parser.getConstructor(parArgTypes); + Object[] parArgs = new Object[]{tokens}; // assign value to parser's args + Object parObj = parConstructor.newInstance(parArgs); // makes new instance of parser + + Method ruleName = parser.getMethod(testRuleName); + + /** Invoke grammar rule, and store if there is a return value */ + Object ruleReturn = ruleName.invoke(parObj); + + /** If rule has return value, determine if it contains an AST or a ST */ + if ( ruleReturn!=null ) { + if ( ruleReturn.getClass().toString().indexOf(testRuleName+"_return")>0 ) { + try { // NullPointerException may happen here... + String classPath = parser.getName(); + if (null != superGrammarName) + classPath += "_" + superGrammarName; + Class _return = Class.forName(classPath+"$"+testRuleName+"_return"); + Method[] methods = _return.getDeclaredMethods(); + for(Method method : methods) { + if ( method.getName().equals("getTree") ) { + Method returnName = _return.getMethod("getTree"); + CommonTree tree = (CommonTree) returnName.invoke(ruleReturn); + result = tree.toStringTree(); + } + else if ( method.getName().equals("getTemplate") ) { + Method returnName = _return.getMethod("getTemplate"); + StringTemplate st = (StringTemplate) returnName.invoke(ruleReturn); + result = st.toString(); + } + } + } + catch(Exception e) { + throw(e); // Note: If any exception occurs, the test is viewed as failed. + } + } + } + + + /** Invalid input */ + if ( tokens.index()!=tokens.size() ) { + throw new RuntimeException("Invalid input."); + } + + return result; + } + + } Added: incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-support/src/test/java/org/apache/chemistry/opencmis/server/support/query/TestParserExt.java URL: http://svn.apache.org/viewvc/incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-support/src/test/java/org/apache/chemistry/opencmis/server/support/query/TestParserExt.java?rev=963193&view=auto ============================================================================== --- incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-support/src/test/java/org/apache/chemistry/opencmis/server/support/query/TestParserExt.java (added) +++ incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-support/src/test/java/org/apache/chemistry/opencmis/server/support/query/TestParserExt.java Mon Jul 12 06:41:49 2010 @@ -0,0 +1,67 @@ +/* + * 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.server.support.query; + +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 TestParserExt extends AbstractParserTst { + + private static Log log = LogFactory.getLog(TestParserStrict.class); + + @Before + public void setUp() throws Exception { + super.setUp(CmisQlStrictLexer.class, CmisQlExtParser.class, null); + } + + @After + public void tearDown() throws Exception { + super.tearDown(); + } + + @Test + public void test_predicate1() throws Exception { + testParser("value_expression", "LOWER(foo)", "(FUNC LOWER (COL foo))"); + } + + @Test + public void test_query1() throws Exception { + testParser("query", "SELECT DISTINCT a, b, c FROM Document", "(SELECT DISTINCT (LIST (COL a) (COL b) (COL c)) (FROM (TABLE Document)))"); + } + + @Test + public void test_query2() throws Exception { + testParserOk("query", + "SELECT Y.CLAIM_NUM, X.PROPERTY_ADDRESS, Y.DAMAGE_ESTIMATES " + + "FROM POLICY AS X JOIN CLAIMS AS Y ON X.POLICY_NUM = Y.POLICY_NUM " + + " WHERE ( 100000 <= ANY Y.DAMAGE_ESTIMATES ) AND ( Y.CAUSE NOT LIKE '%Katrina%' )"); + } + + + @Test + public void test_query3() throws Exception { + testParserOk("query", + "SELECT OBJECT_ID, SCORE() AS X, DESTINATION, DEPARTURE_DATES " + + "FROM TRAVEL_BROCHURE " + + "WHERE ( CONTAINS('CARIBBEAN CENTRAL AMERICA CRUISE TOUR') ) AND( '2010-1-1' < ANY DEPARTURE_DATES )"); + } +} Added: incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-support/src/test/java/org/apache/chemistry/opencmis/server/support/query/TestParserStrict.java URL: http://svn.apache.org/viewvc/incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-support/src/test/java/org/apache/chemistry/opencmis/server/support/query/TestParserStrict.java?rev=963193&view=auto ============================================================================== --- incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-support/src/test/java/org/apache/chemistry/opencmis/server/support/query/TestParserStrict.java (added) +++ incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-support/src/test/java/org/apache/chemistry/opencmis/server/support/query/TestParserStrict.java Mon Jul 12 06:41:49 2010 @@ -0,0 +1,723 @@ +/* + * 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.server.support.query; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** + * @author Jens + * + */ +public class TestParserStrict extends AbstractParserTst{ + + private static Log log = LogFactory.getLog(TestParserStrict.class); + + @Before + public void setUp() throws Exception { + super.setUp(CmisQlStrictLexer.class, CmisQlStrictParser.class, "CmisBaseGrammar"); + } + + @After + public void tearDown() throws Exception { + super.tearDown(); + } + + + // ----- Lexer tests ----- + + // ID: + @Test + public void testID1() throws Exception { + testLexerOk("ID", "a"); + } + +// "toto" OK + @Test + public void testID2() throws Exception { + testLexerFail("ID", "!"); + } + + @Test + public void testID3() throws Exception { + testLexerOk("ID", "toto"); + } + +// "toto123" OK + @Test + public void testID4() throws Exception { + testLexerOk("ID", "toto123"); + } + +// "toto123_" OK + @Test + public void testID5() throws Exception { + testLexerOk("ID", "toto123_"); + } + +// "_foo" OK + @Test + public void testID6() throws Exception { + testLexerOk("ID", "_foo"); + } + +// "foo:bar" OK + @Test + public void testID7() throws Exception { + testLexerOk("ID", "foo:bar"); + } + +// "123" FAIL + @Test + public void testID8() throws Exception { + testLexerFail("ID", "123"); + } +// "123abc" FAIL + @Test + public void testID9() throws Exception { + testLexerFail("ID", "123abc"); + } + +// NUM_LIT: +// "123" OK + @Test + public void testNUM_LIT1() throws Exception { + testLexerOk("NUM_LIT", "123"); + } + +// "0" OK + @Test + public void testNUM_LIT2() throws Exception { + testLexerOk("NUM_LIT", "0"); + } + +// "-0" OK + @Test + public void testNUM_LIT3() throws Exception { + testLexerOk("NUM_LIT", "-0"); + } + +// "1" OK + @Test + public void testNUM_LIT4() throws Exception { + testLexerOk("NUM_LIT", "1"); + } + +// "-1" OK + @Test + public void testNUM_LIT5() throws Exception { + testLexerOk("NUM_LIT", "-1"); + } + +// "-123" OK + @Test + public void testNUM_LIT6() throws Exception { + testLexerOk("NUM_LIT", "123"); + } + +// "0123" OK + @Test + public void testNUM_LIT7() throws Exception { + testLexerOk("NUM_LIT", "0123"); + } + +// "-0123" OK + @Test + public void testNUM_LIT8() throws Exception { + testLexerOk("NUM_LIT", "-0123"); + } + +// "123abc" FAIL + @Test + public void testNUM_LIT9() throws Exception { + testLexerFail("NUM_LIT", "123abc"); + } + +// "123E" FAIL + @Test + public void testNUM_LIT10() throws Exception { + testLexerFail("NUM_LIT", "123E"); + } + +// "123.456" OK + @Test + public void testNUM_LIT11() throws Exception { + testLexerOk("NUM_LIT", "123.456"); + } + +// "+123.456" OK + @Test + public void testNUM_LIT12() throws Exception { + testLexerOk("NUM_LIT", "+123.456"); + } + +// "-123.456" OK + @Test + public void testNUM_LIT13() throws Exception { + testLexerOk("NUM_LIT", "-123.456"); + } + +// ".456" OK + @Test + public void testNUM_LIT14() throws Exception { + testLexerOk("NUM_LIT", ".456"); + } + +// "+.456" OK + @Test + public void testNUM_LIT15() throws Exception { + testLexerOk("NUM_LIT", "+.456"); + } + +// "-.456" OK + @Test + public void testNUM_LIT16() throws Exception { + testLexerOk("NUM_LIT", "-.456"); + } + +// "123." OK + @Test + public void testNUM_LIT17() throws Exception { + testLexerOk("NUM_LIT", "123."); + } + +// "+123." OK + @Test + public void testNUM_LIT18() throws Exception { + testLexerOk("NUM_LIT", "+123."); + } + +// "-123." OK + @Test + public void testNUM_LIT19() throws Exception { + testLexerOk("NUM_LIT", "-123."); + } + +// "+123.456E78" OK + @Test + public void testNUM_LIT20() throws Exception { + testLexerOk("NUM_LIT", "+123.456E78"); + } + +// "-123.456E-78" OK + @Test + public void testNUM_LIT21() throws Exception { + testLexerOk("NUM_LIT", "-123.456E-78"); + } + +// ".456E78" OK + @Test + public void testNUM_LIT22() throws Exception { + testLexerOk("NUM_LIT", ".456E78"); + } + +// "+123.E+78" OK + @Test + public void testNUM_LIT23() throws Exception { + testLexerOk("NUM_LIT", "+123.E+78"); + } + +// STRING_LIT: +// "'abc'" OK + @Test + public void testSTRING_LIT1() throws Exception { + testLexerOk("STRING_LIT", "'abc'"); + } + +// "'a''bc'" OK + @Test + public void testSTRING_LIT2() throws Exception { + testLexerOk("STRING_LIT", "'a''bc'"); + } + +// "'abc" FAIL + @Test + public void testSTRING_LIT3() throws Exception { + testLexerFail("STRING_LIT", "'abc"); + } + +// "abc'" FAIL + @Test + public void testSTRING_LIT4() throws Exception { + testLexerFail("STRING_LIT", "abc'"); + } + +// "'ab'c'" FAIL + @Test + public void testSTRING_LIT5() throws Exception { + testLexerFail("STRING_LIT", "'ab'c'"); + } + + +// BOOL_LIT: +// "TRUE" OK + @Test + public void testBOOL_LIT1() throws Exception { + testLexerOk("BOOL_LIT", "TRUE"); + } + +// "true" OK + @Test + public void testSBOOL_LIT2() throws Exception { + testLexerOk("BOOL_LIT", "true"); + } + +// "FALSE" OK + @Test + public void testBOOL_LIT3() throws Exception { + testLexerOk("BOOL_LIT", "FALSE"); + } + +// "false" OK + @Test + public void testBOOL_LIT4() throws Exception { + testLexerOk("BOOL_LIT", "false"); + } + + +// TIME_LIT: +// "TIMESTAMP '2010-01-01Z01:01:01.000Z'" OK + @Test + public void testTIME_LIT1() throws Exception { + testLexerOk("TIME_LIT", "TIMESTAMP '2010-01-01Z01:01:01.000Z'"); + } + +// "timestamp '123'" OK + @Test + public void testTIME_LIT2() throws Exception { + testLexerOk("TIME_LIT", "timestamp '123'"); + } + +// "TIMESTAMP 123" FAIL + @Test + public void testTIME_LIT3() throws Exception { + testLexerFail("TIME_LIT", "TIMESTAMP 123"); + } + + + // ----- Parser tests ----- + +// literal: +// "123" OK + @Test + public void testLiteral1() throws Exception { + testParserOk("literal", "123"); + } + +// "-123" OK + @Test + public void testLiteral2() throws Exception { + testParserOk("literal", "123"); + } + +// "0" OK + @Test + public void testLiteral3() throws Exception { + testParserOk("literal", "0"); + } + +// "0123" OK + @Test + public void testLiteral4() throws Exception { + testParserOk("literal", "0123"); + } + + // "abc123" OK +// "123abc" FAIL + @Test + public void testLiteral5() throws Exception { + testParserFail("literal", "123abc"); + } + +// "'abc'" OK + @Test + public void testLiteral6() throws Exception { + testParserOk("literal", "'abc'"); + } + +// "123.345E78" OK + @Test + public void testLiteral7() throws Exception { + testParserOk("literal", "123.345E78"); + } + + +// order_by_clause: +// "ORDER BY foo" -> (ORDER_BY (COL foo) ASC) + @Test + public void testOrderBy1() throws Exception { + testParser("order_by_clause", "ORDER BY foo", "(ORDER_BY (COL foo) ASC)"); + } + +// "ORDER BY foo ASC" -> (ORDER_BY (COL foo) ASC) + @Test + public void testOrderBy2() throws Exception { + testParser("order_by_clause", "ORDER BY foo ASC", "ORDER_BY (COL foo) ASC)"); + } + +// "ORDER BY foo DESC" -> (ORDER_BY (COL foo) DESC) + @Test + public void testOrderBy3() throws Exception { + testParser("order_by_clause", "ORDER BY foo DESC", "(ORDER_BY (COL foo) DESC)"); + } + +// "ORDER BY t.foo, bar DESC" -> (ORDER_BY (COL t foo) ASC (COL bar) DESC) + @Test + public void testOrderBy4() throws Exception { + testParser("order_by_clause", "ORDER BY t.foo, bar DESC", "(ORDER_BY (COL t foo) ASC (COL bar) DESC)"); + } + + +// column_reference: +// "foo" -> (COL foo) + @Test + public void test_column_reference1() throws Exception { + testParser("column_reference", "foo", "(COL foo)"); + } + +// "bar.foo" -> (COL bar foo) + @Test + public void test_column_reference2() throws Exception { + testParser("column_reference", "bar.foo", "(COL bar foo)"); + } + + +// from_clause: +// "FROM foo JOIN bar ON x = y" -> (FROM (TABLE foo) (JOIN INNER (TABLE bar) (ON (COL x) = (COL y)))) + @Test + public void testFrom() throws Exception { + testParser("from_clause", "FROM foo JOIN bar ON x = y", "(FROM (TABLE foo) (JOIN INNER (TABLE bar) (ON (COL x) = (COL y))))"); + } + +// table_join: +// "LEFT OUTER JOIN foo ON x = y" -> (JOIN LEFT (TABLE foo) (ON (COL x) = (COL y))) + @Test + public void test_column_reference11() throws Exception { + testParser("table_join", "LEFT OUTER JOIN foo ON x = y", "(JOIN LEFT (TABLE foo) (ON (COL x) = (COL y)))"); + } + +// "INNER JOIN foo" -> (JOIN INNER (TABLE foo)) + @Test + public void test_column_reference12() throws Exception { + testParser("table_join", "INNER JOIN foo" , "(JOIN INNER (TABLE foo))"); + } + +// one_table: +// "foo" -> (TABLE foo) + @Test + public void test_column_reference3() throws Exception { + testParser("one_table", "foo", "(TABLE foo)"); + } + +// "foo bar" -> (TABLE foo bar) + @Test + public void test_column_reference4() throws Exception { + testParser("one_table", "foo bar", "(TABLE foo bar)"); + } + +// "foo AS bar" -> (TABLE foo bar) + @Test + public void test_column_reference5() throws Exception { + testParser("one_table", "foo AS bar", "(TABLE foo bar)"); + } + +// "(foo)" -> (TABLE foo) + @Test + public void test_column_reference6() throws Exception { + testParser("one_table", "(foo)", "(TABLE foo)"); + } + +// in_predicate: +// "foo IN ( 'a', 'b', 'c')" -> (IN (COL foo) (IN_LIST 'a' 'b' 'c')) + @Test + public void test_in_predicate1() throws Exception { + testParser("in_predicate", "foo IN ( 'a', 'b', 'c')", "(IN (COL foo) (IN_LIST 'a' 'b' 'c'))"); + } + +// "foo NOT IN ( 1, 2, 3)" -> (NOT_IN (COL foo) (IN_LIST 1 2 3)) + @Test + public void test_in_predicate2() throws Exception { + testParser("in_predicate", "foo NOT IN ( 1, 2, 3)", "(NOT_IN (COL foo) (IN_LIST 1 2 3))"); + } + + +// quantified_in_predicate: +// "ANY foo IN ('a', 1)" -> (IN_ANY (COL foo) (IN_LIST 'a' 1)) + @Test + public void tes_quantified_in_predicate() throws Exception { + testParser("quantified_in_predicate", "ANY foo IN ('a', 1)", "(IN_ANY (COL foo) (IN_LIST 'a' 1))"); + } + + +// comparison_predicate: +// "foo = 1" -> (= (COL foo) 1) + @Test + public void test_comparison_predicate1() throws Exception { + testParser("comparison_predicate", "foo = 1", "(= (COL foo) 1)"); + } + +// "foo <> 1" -> (<> (COL foo) 1) + @Test + public void test_comparison_predicate2() throws Exception { + testParser("comparison_predicate", "foo <> 1", "(<> (COL foo) 1)"); + } + +// +// predicate: +// "foo = 1" -> (= (COL foo) 1) + @Test + public void test_predicate1() throws Exception { + testParser("predicate", "foo = 1", "(= (COL foo) 1)"); + } + +// "foo IN ('bar')" -> (IN (COL foo) (IN_LIST 'bar')) + @Test + public void test_predicate2() throws Exception { + testParser("predicate", "foo IN ('bar')", "(IN (COL foo) (IN_LIST 'bar'))"); + } + +// "foo IS NULL" -> (IS_NULL (COL foo)) + @Test + public void test_predicate3() throws Exception { + testParser("predicate","foo IS NULL", "(IS_NULL (COL foo))"); + } + +// "foo IS NOT NULL" -> (IS_NOT_NULL (COL foo)) + @Test + public void test_predicate4() throws Exception { + testParser("predicate", "foo IS NOT NULL", "(IS_NOT_NULL (COL foo))"); + } + +// "1 = ANY foo" -> (EQ_ANY 1 (COL foo)) + @Test + public void test_predicate5() throws Exception { + testParser("predicate", "1 = ANY foo", "(EQ_ANY 1 (COL foo))"); + } + +// "SCORE() = 'bar'" -> (= SCORE 'bar') + @Test + public void test_predicate6() throws Exception { + testParser("predicate", "SCORE() = 'bar'", "(= SCORE 'bar')"); + } + + +// boolean_term: +// "c >= 3 AND d <= 4" -> (AND (>= (COL c) 3) (<= (COL d) 4)) + @Test + public void boolean_term1() throws Exception { + testParser("boolean_term", "c >= 3 AND d <= 4", "(AND (>= (COL c) 3) (<= (COL d) 4))"); + } + +// "c >= 3 AND NOT d <= 4" -> (AND (>= (COL c) 3) (NOT (<= (COL d) 4))) + @Test + public void boolean_term2() throws Exception { + testParser("boolean_term", "c >= 3 AND NOT d <= 4", "(AND (>= (COL c) 3) (NOT (<= (COL d) 4)))"); + } + + +// folder_predicate: +// "IN_FOLDER(foo,'ID123')" -> (IN_FOLDER foo 'ID123') + @Test + public void folder_predicate1() throws Exception { + testParser("folder_predicate", "IN_FOLDER(foo,'ID123')", "(IN_FOLDER foo 'ID123')"); + } + +// "IN_FOLDER('ID123')" -> (IN_FOLDER 'ID123') + @Test + public void folder_predicate2() throws Exception { + testParser("folder_predicate", "IN_FOLDER('ID123')", "(IN_FOLDER 'ID123')"); + } + +// "IN_TREE(foo,'ID123')" -> (IN_TREE foo 'ID123') + @Test + public void folder_predicate3() throws Exception { + testParser("folder_predicate", "IN_TREE(foo,'ID123')", "(IN_FOLDER 'ID123')"); + } + +// "IN_TREE('ID123')" -> (IN_TREE 'ID123') + @Test + public void folder_predicate4() throws Exception { + testParser("folder_predicate","IN_TREE('ID123')" , " (IN_TREE 'ID123')"); + } + + +// text_search_predicate: +// "CONTAINS('foo')" -> (CONTAINS 'foo') + @Test + public void text_search_predicate1() throws Exception { + testParser("text_search_predicate", "CONTAINS('foo')", "(CONTAINS 'foo')"); + } + +// "CONTAINS(bar, 'foo')" -> (CONTAINS bar 'foo') + @Test + public void text_search_predicate2() throws Exception { + testParser("text_search_predicate", "CONTAINS(bar, 'foo')", "(CONTAINS bar 'foo')"); + } + + +// where_clause: +// "WHERE foo = 1" -> (WHERE (= (COL foo) 1)) + @Test + public void test_where_clause1() throws Exception { + testParser("where_clause", "WHERE foo = 1", "(WHERE (= (COL foo) 1))"); + } + +// "WHERE a = 1 AND b <> 2 OR c >= 3" -> (WHERE (OR (AND (= (COL a) 1) (<> (COL b) 2)) (>= (COL c) 3))) + @Test + public void test_where_clause2() throws Exception { + testParser("where_clause", "WHERE a = 1 AND b <> 2 OR c >= 3", "(WHERE (OR (AND (= (COL a) 1) (<> (COL b) 2)) (>= (COL c) 3)))"); + } + +// "WHERE a = 1 AND b <> 2 OR c >= 3 AND d <= 4" -> (WHERE (OR (AND (= (COL a) 1) (<> (COL b) 2)) (AND (>= (COL c) 3) (<= (COL d) 4)))) + @Test + public void test_where_clause3() throws Exception { + testParser("where_clause", "WHERE a = 1 AND b <> 2 OR c >= 3 AND d <= 4", "(WHERE (OR (AND (= (COL a) 1) (<> (COL b) 2)) (AND (>= (COL c) 3) (<= (COL d) 4))))"); + } + +// "WHERE a = 1 AND b <> 2 OR c >= 3 AND NOT d <= 4" -> (WHERE (OR (AND (= (COL a) 1) (<> (COL b) 2)) (AND (>= (COL c) 3) (NOT (<= (COL d) 4))))) + @Test + public void test_where_clause4() throws Exception { + testParser("where_clause", "WHERE a = 1 AND b <> 2 OR c >= 3 AND NOT d <= 4", "(WHERE (OR (AND (= (COL a) 1) (<> (COL b) 2)) (AND (>= (COL c) 3) (NOT (<= (COL d) 4)))))"); + } + + +// query: +// "SELECT * FROM Document" -> (SELECT * (FROM (TABLE Document))) + @Test + public void test_query1() throws Exception { + testParser("query", "SELECT * FROM Document", "(SELECT * (FROM (TABLE Document)))"); + } + +// "SELECT a, b, c FROM Document" -> (SELECT (SEL_LIST (COL a) (COL b) (COL c)) (FROM (TABLE Document))) + @Test + public void test_query2() throws Exception { + testParser("query", "SELECT a, b, c FROM Document", "(SELECT (SEL_LIST (COL a) (COL b) (COL c)) (FROM (TABLE Document)))"); + } + +// "SELECT a, b FROM Document ORDER BY a, b" -> (SELECT (SEL_LIST (COL a) (COL b)) (FROM (TABLE Document)) (ORDER_BY (COL a) ASC (COL b) ASC)) + @Test + public void test_query3() throws Exception { + testParser("query", "SELECT a, b FROM Document ORDER BY a, b", "(SELECT (SEL_LIST (COL a) (COL b)) (FROM (TABLE Document)) (ORDER_BY (COL a) ASC (COL b) ASC))"); + } + + +// where_clause: +// "WHERE IN_TREE('ID00093854763') AND ('SMITH' = ANY AUTHORS)" -> (WHERE (AND (IN_TREE 'ID00093854763') (EQ_ANY 'SMITH' (COL AUTHORS)))) + @Test + public void test_where_clause5() throws Exception { + testParser("where_clause", "WHERE IN_TREE('ID00093854763') AND ('SMITH' = ANY AUTHORS)", "(WHERE (AND (IN_TREE 'ID00093854763') (EQ_ANY 'SMITH' (COL AUTHORS))))"); + } + + +// query: +// +// << +// SELECT * FROM Document WHERE foo = 1 +// >> -> (SELECT * (FROM (TABLE Document)) (WHERE (= (COL foo) 1))) + @Test + public void query1() throws Exception { + testParser("query", "SELECT * FROM Document WHERE foo = 1", + "(SELECT * (FROM (TABLE Document)) (WHERE (= (COL foo) 1)))"); + } + + + // Examples from older versions of the specs. + + +// << +// SELECT * FROM WHITE_PAPER +// >> -> (SELECT * (FROM (TABLE WHITE_PAPER))) + @Test + public void query2() throws Exception { + testParser("query", "SELECT * FROM WHITE_PAPER", "(SELECT * (FROM (TABLE WHITE_PAPER)))"); + } + + +// << +// SELECT TITLE, AUTHORS, DATE +// FROM WHITE_PAPER +// WHERE ( IN_TREE('ID00093854763') ) AND ( 'SMITH' = ANY AUTHORS ) +// >> -> (SELECT (SEL_LIST (COL TITLE) (COL AUTHORS) (COL DATE)) (FROM (TABLE WHITE_PAPER)) (WHERE (AND (IN_TREE 'ID00093854763') (EQ_ANY 'SMITH' (COL AUTHORS))))) + @Test + public void query3() throws Exception { + testParser("query", + "SELECT TITLE, AUTHORS, DATE " + + "FROM WHITE_PAPER " + + "WHERE ( IN_TREE('ID00093854763') ) AND ( 'SMITH' = ANY AUTHORS )", + "(SELECT (SEL_LIST (COL TITLE) (COL AUTHORS) (COL DATE)) (FROM (TABLE WHITE_PAPER)) (WHERE (AND (IN_TREE 'ID00093854763') (EQ_ANY 'SMITH' (COL AUTHORS)))))"); + } + + +// << +// SELECT Y.CLAIM_NUM, X.PROPERTY_ADDRESS, Y.DAMAGE_ESTIMATES +// FROM POLICY AS X JOIN CLAIMS AS Y ON X.POLICY_NUM = Y.POLICY_NUM +// WHERE ( 100000 = ANY Y.DAMAGE_ESTIMATES ) AND ( Y.CAUSE NOT LIKE '%Katrina%' ) +// >> OK + @Test + public void query4() throws Exception { + testParserOk("query", + "SELECT Y.CLAIM_NUM, X.PROPERTY_ADDRESS, Y.DAMAGE_ESTIMATES " + + "FROM POLICY AS X JOIN CLAIMS AS Y ON X.POLICY_NUM = Y.POLICY_NUM " + + "WHERE ( 100000 = ANY Y.DAMAGE_ESTIMATES ) AND ( Y.CAUSE NOT LIKE '%Katrina%' )"); + } + + +// << +// SELECT Y.CLAIM_NUM, X.PROPERTY_ADDRESS, Y.DAMAGE_ESTIMATES +// FROM POLICY AS X JOIN CLAIMS AS Y ON X.POLICY_NUM = Y.POLICY_NUM +// WHERE ( 100000 <= ANY Y.DAMAGE_ESTIMATES ) AND ( Y.CAUSE NOT LIKE '%Katrina%' ) +// >> FAIL + @Test + public void query5() throws Exception { + testParserFail("query", + "SELECT Y.CLAIM_NUM, X.PROPERTY_ADDRESS, Y.DAMAGE_ESTIMATES " + + "FROM POLICY AS X JOIN CLAIMS AS Y ON X.POLICY_NUM = Y.POLICY_NUM " + + " WHERE ( 100000 <= ANY Y.DAMAGE_ESTIMATES ) AND ( Y.CAUSE NOT LIKE '%Katrina%' )"); + } + + +// << +// SELECT * +// FROM CAR_REVIEW +// WHERE ANY FEATURES IN ('NAVIGATION SYSTEM', 'SATELLITE RADIO', 'MP3' ) +// >> OK + @Test + public void query6() throws Exception { + testParserOk("query", " SELECT * FROM CAR_REVIEW WHERE ANY FEATURES IN ('NAVIGATION SYSTEM', 'SATELLITE RADIO', 'MP3' )"); + } + + +// << +// SELECT OBJECT_ID, SCORE() AS X, DESTINATION, DEPARTURE_DATES +// FROM TRAVEL_BROCHURE +// WHERE ( CONTAINS('CARIBBEAN CENTRAL AMERICA CRUISE TOUR') ) AND +// ( '2010-1-1' = ANY DEPARTURE_DATES ) +// ORDER BY X DESC +// >> OK + @Test + public void query7() throws Exception { + testParserOk("query", + "SELECT OBJECT_ID, SCORE() AS X, DESTINATION, DEPARTURE_DATES " + + "FROM TRAVEL_BROCHURE " + + "WHERE ( CONTAINS('CARIBBEAN CENTRAL AMERICA CRUISE TOUR') ) AND( '2010-1-1' = ANY DEPARTURE_DATES )"); + } +}