This project has retired. For details please refer to its Attic page.
QueryParseTest xref

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   * http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.chemistry.opencmis.inmemory.query;
20  
21  import static org.junit.Assert.assertEquals;
22  import static org.junit.Assert.assertFalse;
23  import static org.junit.Assert.assertNotNull;
24  import static org.junit.Assert.assertNull;
25  import static org.junit.Assert.assertTrue;
26  import static org.junit.Assert.fail;
27  
28  import java.util.List;
29  import java.util.Map;
30  
31  import org.antlr.runtime.FailedPredicateException;
32  import org.antlr.runtime.RecognitionException;
33  import org.antlr.runtime.tree.CommonTree;
34  import org.antlr.runtime.tree.Tree;
35  import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException;
36  import org.apache.chemistry.opencmis.server.support.query.CmisQlStrictLexer;
37  import org.apache.chemistry.opencmis.server.support.query.CmisQueryWalker;
38  import org.apache.chemistry.opencmis.server.support.query.CmisSelector;
39  import org.apache.chemistry.opencmis.server.support.query.ColumnReference;
40  import org.apache.chemistry.opencmis.server.support.query.FunctionReference;
41  import org.apache.chemistry.opencmis.server.support.query.QueryObject;
42  import org.apache.chemistry.opencmis.server.support.query.QueryObject.SortSpec;
43  import org.apache.chemistry.opencmis.server.support.query.TextSearchLexer;
44  import org.apache.commons.logging.Log;
45  import org.apache.commons.logging.LogFactory;
46  import org.junit.Before;
47  import org.junit.Test;
48  
49  public class QueryParseTest extends AbstractQueryTest {
50  
51      private static final Log LOG = LogFactory.getLog(QueryParseTest.class);
52  
53      @Before
54      public void setUp() {
55          // initialize query object, we do not need a type manager for just testing parsing
56          super.setUp(new QueryObject(null), null);
57      }
58  
59      @Test
60      public void simpleFailTest() {
61          String statement = "SELECT * TO MyType ORDER BY abc.def ASC";
62  //        String statement = "SELECT dsfj disfj dsifj dsoijf�039fi ";
63          try {
64              traverseStatement(statement);
65              fail("Errornous statement should throw exception.");
66          } catch (Exception e) {
67              LOG.debug("Exception in simpleFailTest: " + e);
68          }
69      }
70  
71      public void simpleSelectTest1() {
72          String statement = "SELECT SCORE() FROM cmis:document";
73  
74          CmisQueryWalker walker = traverseStatementAndCatchExc(statement);
75          assertNotNull(walker);
76  
77          List<CmisSelector> selects = queryObj.getSelectReferences();
78          assertTrue(1 == selects.size());
79          assertTrue(selects.get(0) instanceof FunctionReference);
80  
81          FunctionReference funcRef = ((FunctionReference)selects.get(0));
82          assertTrue(FunctionReference.CmisQlFunction.SCORE == funcRef.getFunction());
83      }
84  
85      @Test
86      public void simpleSelectTest2() {
87          String statement = "SELECT abc FROM cmis:document";
88          CmisQueryWalker walker = traverseStatementAndCatchExc(statement);
89          assertNotNull(walker);
90  
91          List<CmisSelector> selects = queryObj.getSelectReferences();
92          assertTrue(1 == selects.size());
93          // nothing should be in where references
94          assertTrue(0 == queryObj.getWhereReferences().size());
95  
96          ColumnReference colRef = ((ColumnReference)selects.get(0));
97          assertTrue(selects.get(0) instanceof ColumnReference);
98          assertEquals("abc", colRef.getPropertyQueryName());
99      }
100 
101     @Test
102     public void simpleSelectTest3() {
103         String statement = "SELECT t1.abc FROM cmis:document";
104         CmisQueryWalker walker = traverseStatementAndCatchExc(statement);
105         assertNotNull(walker);
106 
107         List<CmisSelector> selects = queryObj.getSelectReferences();
108         assertTrue(1 == selects.size());
109         // nothing should be in where references
110         assertTrue(0 == queryObj.getWhereReferences().size());
111         assertTrue(selects.get(0) instanceof ColumnReference);
112 
113         ColumnReference colRef = ((ColumnReference)selects.get(0));
114         assertEquals("t1", colRef.getQualifier());
115         assertEquals("abc", colRef.getPropertyQueryName());
116     }
117 
118     @Test
119     public void simpleSelectTest4() {
120         String statement = "SELECT * FROM cmis:document";
121         CmisQueryWalker walker = traverseStatementAndCatchExc(statement);
122         assertNotNull(walker);
123 
124         List<CmisSelector> selects = queryObj.getSelectReferences();
125         assertTrue(1 == selects.size());
126         // nothing should be in where references
127         assertTrue(0 == queryObj.getWhereReferences().size());
128 
129         ColumnReference colRef = ((ColumnReference)selects.get(0));
130         assertTrue(selects.get(0) instanceof ColumnReference);
131         assertEquals(null, colRef.getQualifier());
132         assertEquals("*", colRef.getPropertyQueryName());
133     }
134 
135     @Test
136     public void simpleSelectTest5() {
137         String statement = "SELECT t1.* FROM cmis:document";
138         CmisQueryWalker walker = traverseStatementAndCatchExc(statement);
139         assertNotNull(walker);
140 
141         List<CmisSelector> selects = queryObj.getSelectReferences();
142         assertTrue(1 == selects.size());
143         // nothing should be in where references
144         assertTrue(0 == queryObj.getWhereReferences().size());
145         assertTrue(selects.get(0) instanceof ColumnReference);
146 
147         ColumnReference colRef = ((ColumnReference)selects.get(0));
148         assertEquals("t1", colRef.getQualifier());
149         assertEquals("*", colRef.getPropertyQueryName());
150     }
151 
152     @Test
153     public void simpleSelectTest6() {
154         String statement = "SELECT t2.aaa myalias FROM cmis:document";
155         CmisQueryWalker walker = traverseStatementAndCatchExc(statement);
156         assertNotNull(walker);
157 
158         List<CmisSelector> selects = queryObj.getSelectReferences();
159         assertTrue(1 == selects.size());
160         // nothing should be in where references
161         assertTrue(0 == queryObj.getWhereReferences().size());
162         assertTrue(selects.get(0) instanceof ColumnReference);
163 
164         ColumnReference colRef = ((ColumnReference)selects.get(0));
165         assertEquals("t2", colRef.getQualifier());
166         assertEquals("aaa", colRef.getPropertyQueryName());
167     }
168 
169     @Test
170     public void simpleSelectTest7() {
171         // error processing
172         String statement = "SELECTXXX t2.aaa myalias FROM cmis:document WHERE a < t1";
173         try {
174             CmisQueryWalker walker = traverseStatement(statement);
175             fail("Walking of statement should with RecognitionException but succeeded");
176         } catch (Exception e) {
177             assertTrue(e instanceof CmisInvalidArgumentException);
178         }
179     }
180 
181     @Test
182     public void simpleFromTest1() {
183         String statement = "SELECT * FROM MyType MyAlias";
184 
185         CmisQueryWalker walker = traverseStatementAndCatchExc(statement);
186         assertNotNull(walker);
187 
188         Map<String,String> types = queryObj.getTypes();
189         assertTrue(1 == types.size());
190 
191         String key = types.keySet().iterator().next();
192         assertEquals("MyAlias", key);
193         assertEquals("MyType", types.get(key));
194     }
195 
196     @Test
197     public void simpleFromTest2() {
198         String statement = "SELECT * FROM MyType";
199         CmisQueryWalker walker = traverseStatementAndCatchExc(statement);
200         assertNotNull(walker);
201 
202         Map<String,String> types = queryObj.getTypes();
203         assertTrue(1 == types.size());
204 
205         String key = types.keySet().iterator().next();
206         assertEquals("MyType", key);
207         assertEquals("MyType", types.get(key));
208     }
209 
210     @Test
211     public void simpleFromTest3() {
212         String statement = "SELECT t2.aaa FROM MyType abc123";
213         CmisQueryWalker walker = traverseStatementAndCatchExc(statement);
214         assertNotNull(walker);
215 
216         Map<String,String> types = queryObj.getTypes();
217         assertTrue(1 == types.size());
218 
219         String key = types.keySet().iterator().next();
220         assertEquals("abc123", key);
221         assertEquals("MyType", types.get(key));
222     }
223 
224     @Test
225     public void simpleFromTest4() {
226         String statement = "SELECT X.aaa FROM MyType AS X WHERE 10 = ANY X.aaa ";
227         CmisQueryWalker walker = traverseStatementAndCatchExc(statement);
228         assertNotNull(walker);
229 
230         Map<String,String> types = queryObj.getTypes();
231         assertTrue(1 == types.size());
232 
233         String key = types.keySet().iterator().next();
234         assertEquals("X", key);
235         assertEquals("MyType", types.get(key));
236     }
237 
238     @Test
239     public void simpleWhereTest() {
240         String statement = "SELECT * FROM MyType WHERE MyProp1=123";
241 
242         CmisQueryWalker walker = traverseStatementAndCatchExc(statement);
243         assertNotNull(walker);
244 
245         List<CmisSelector> whereRefs = queryObj.getWhereReferences();
246         Map<Integer, CmisSelector> colRefs = queryObj.getColumnReferences();
247         assertTrue(1 == whereRefs.size());
248 
249         CmisSelector value = whereRefs.iterator().next();
250         assertTrue(value instanceof ColumnReference);
251         assertEquals("MyProp1", ((ColumnReference)value).getPropertyQueryName());
252         // only "*" should be in select references
253         assertTrue(1 == queryObj.getSelectReferences().size());
254 
255         CommonTree tree = (CommonTree) walker.getTreeNodeStream().getTreeSource();
256 
257         // System.out.println("simpleWhereTest printing Tree ...");
258         // System.out.println("id in map: " + System.identityHashCode(whereRefs.keySet().iterator().next()));
259 //        assertTrue(traverseTreeAndFindNodeInColumnMap(tree, colRefs));
260         traverseTreeAndFindNodeInColumnMap2(tree, colRefs);
261         // System.out.println("... simpleWhereTest printing Tree done.");
262     }
263 
264     // check if the map containing all column references in the where clause has an existing node as key
265     private boolean traverseTreeAndFindNodeInColumnMap(Tree node, Map<Object, CmisSelector> colRefs) {
266         boolean found = false;
267 //        System.out.println("cmp to: " + System.identityHashCode(node) + " is: " + node.toString());
268         if (null != colRefs.get(node)) {
269             return true;
270         }
271 
272         int count = node.getChildCount();
273         for (int i=0; i<count && !found; i++) {
274             Tree child = node.getChild(i);
275             found = traverseTreeAndFindNodeInColumnMap(child, colRefs);
276         }
277         return found;
278     }
279 
280     private boolean traverseTreeAndFindNodeInColumnMap2(Tree node, Object colRef) {
281         int count = node.getChildCount();
282         LOG.debug("  checking with: " + node + " identity hash code: " + System.identityHashCode(node));
283         if (node==colRef) {
284             return true;
285         }
286         boolean found = false;
287         for (int i=0; i<count && !found; i++) {
288             Tree child = node.getChild(i);
289             found = traverseTreeAndFindNodeInColumnMap2(child, colRef);
290         }
291         return found;
292     }
293 
294     @Test
295     public void simpleSortTest1() {
296         String statement = "SELECT * FROM MyType ORDER BY abc.def ASC";
297 
298         CmisQueryWalker walker = traverseStatementAndCatchExc(statement);
299         assertNotNull(walker);
300 
301         List<SortSpec> orderBys = queryObj.getOrderBys();
302         assertTrue(1 == orderBys.size());
303 
304         SortSpec sp = orderBys.get(0);
305         assertTrue(sp.isAscending());
306 
307         CmisSelector sortSpec = sp.getSelector();
308         assert(sortSpec instanceof ColumnReference);
309         assertEquals("abc", ((ColumnReference)sortSpec).getQualifier());
310         assertEquals("def", ((ColumnReference)sortSpec).getPropertyQueryName());
311     }
312 
313     @Test
314     public void simpleSortTest2() {
315         String statement = "SELECT * FROM MyType ORDER BY def DESC";
316         CmisQueryWalker walker = traverseStatementAndCatchExc(statement);
317         assertNotNull(walker);
318 
319         List<SortSpec> orderBys = queryObj.getOrderBys();
320         assertTrue(1 == orderBys.size());
321 
322         SortSpec sp = orderBys.get(0);
323         assertFalse(sp.isAscending());
324 
325         CmisSelector sortSpec = sp.getSelector();
326         assert(sortSpec instanceof ColumnReference);
327         assertNull(((ColumnReference)sortSpec).getQualifier());
328         assertEquals("def", ((ColumnReference)sortSpec).getPropertyQueryName());
329     }
330 
331     @Test
332     public void printTreeTest() {
333         // System.out.println("printTreeTest():");
334         String statement = "SELECT p1, p2, p3.t3 mycol FROM MyType AS MyAlias WHERE p1='abc' and p2=123 ORDER BY abc.def ASC";
335         try {
336             getWalker(statement);
337             Tree parserTree = (Tree) walker.getTreeNodeStream().getTreeSource();
338             printTree(parserTree, statement);
339 
340         } catch (Exception e) {
341             fail("Cannot parse query: " + statement + " (" + e + ")");
342         }
343     }
344 
345     @Test
346     public void extractWhereTreeTest() {
347         // System.out.println("extractWhereTreeTest():");
348         String statement = "SELECT p1, p2, p3.t3 mycol FROM MyType AS MyAlias WHERE p1='abc' and p2=123 ORDER BY abc.def ASC";
349 
350         try {
351             traverseStatementAndCatchExc(statement);
352             Tree whereTree = walker.getWherePredicateTree(); // getWhereTree(parserTree);
353             printTree(whereTree);
354             LOG.info("Evaluate WHERE subtree: ...");
355             evalWhereTree(whereTree);
356         } catch (Exception e) {
357             fail("Cannot parse query: " + statement + " (" + e + ")");
358         }
359     }
360 
361     @Test
362     public void whereTestIn() {
363         // System.out.println("extractWhereTestIN():");
364         String statement = "SELECT p1 FROM MyType WHERE p1 IN ('Red', 'Green', 'Blue', 'Black')";
365         checkTreeWhere(statement);
366     }
367 
368     @Test
369     public void whereTestEq() {
370         String statement = "SELECT p1 FROM MyType WHERE p1='abc'";
371         checkTreeWhere(statement);
372     }
373 
374     @Test
375     public void whereTestNotEq() {
376         String statement = "SELECT p1 FROM MyType WHERE p1 <> 123";
377         checkTreeWhere(statement);
378     }
379 
380     @Test
381     public void whereTestLT() {
382         String statement = "SELECT p1 FROM MyType WHERE p1 < 123";
383         checkTreeWhere(statement);
384     }
385 
386     @Test
387     public void whereTestGT() {
388         String statement = "SELECT p1 FROM MyType WHERE p1 > 123";
389         checkTreeWhere(statement);
390     }
391 
392     @Test
393     public void whereTestLTEQ() {
394         String statement = "SELECT p1 FROM MyType WHERE p1 <= 123";
395         checkTreeWhere(statement);
396     }
397 
398     @Test
399     public void whereTestGTEQ() {
400         String statement = "SELECT p1 FROM MyType WHERE p1 >= 123";
401         checkTreeWhere(statement);
402     }
403 
404     @Test
405     public void whereTestAnd() {
406         String statement = "SELECT p1 FROM MyType WHERE p1=1 AND p2=2";
407         checkTreeWhere(statement);
408     }
409 
410     @Test
411     public void whereTestOr() {
412         String statement = "SELECT p1 FROM MyType WHERE p1='abc' OR p2=123";
413         checkTreeWhere(statement);
414     }
415 
416     @Test
417     public void whereTestNot() {
418         String statement = "SELECT p1 FROM MyType WHERE NOT p1 = 123";
419         checkTreeWhere(statement);
420     }
421 
422     @Test
423     public void whereTestInFolder() {
424         String statement = "SELECT p1 FROM MyType WHERE IN_FOLDER('myfolder')";
425         checkTreeWhere(statement);
426     }
427 
428     @Test
429     public void whereTestInTree() {
430         String statement = "SELECT p1 FROM MyType WHERE IN_TREE('myfolder')";
431         checkTreeWhere(statement);
432     }
433 
434     @Test
435     public void whereTestAny() {
436         String statement = "SELECT p1 FROM MyType WHERE 'Smith' = ANY Authors ";
437         checkTreeWhere(statement);
438     }
439 
440 
441     @Test
442     public void whereTestAnyIn() {
443         String statement = "SELECT p1 FROM MyType WHERE ANY Colors IN ('Red', 'Green', 'Blue')";
444         checkTreeWhere(statement);
445     }
446 
447     @Test
448     public void whereTestLike() {
449         String statement = "SELECT p1 FROM MyType WHERE p1 LIKE 'abc*' ";
450         checkTreeWhere(statement);
451     }
452 
453     @Test
454     public void whereTestNotLike() {
455         String statement = "SELECT p1 FROM MyType WHERE p1 NOT LIKE 'abc*'";
456         checkTreeWhere(statement);
457     }
458 
459     @Test
460     public void whereTestNull() {
461         String statement = "SELECT p1 FROM MyType WHERE p1 IS NULL";
462         checkTreeWhere(statement);
463     }
464 
465     @Test
466     public void whereTestNotNull() {
467         String statement = "SELECT p1 FROM MyType WHERE p1 IS NOT NULL";
468         checkTreeWhere(statement);
469     }
470 
471     @Test
472     public void whereTestContains() {
473         String statement = "SELECT p1 FROM MyType WHERE CONTAINS('Beethoven')";
474         checkTreeWhere(statement);
475         Tree tree = findSearchExpression(statement);
476         printSearchTree(tree, statement);
477         assertEquals("Beethoven", tree.getChild(0).getText());
478     }
479 
480     @Test
481     public void whereTestContainsNoFulltextParse() throws Exception {
482         String statement = "SELECT p1 FROM MyType WHERE CONTAINS('Beethoven')";
483         walker = getWalker(statement);
484         walker.setDoFullTextParse(false);
485         walker.query(queryObj, predicateWalker);
486         Tree whereTree = walker.getWherePredicateTree();
487         Tree tree = findTextSearchNode(whereTree);
488         printSearchTree(tree, statement);
489         // unparsed, still with quotes
490         assertEquals("'Beethoven'", tree.getChild(0).getText());
491     }
492 
493     @Test
494     public void whereTestScore() {
495         String statement = "SELECT p1 FROM MyType WHERE SCORE() = 100";
496         checkTreeWhere(statement);
497     }
498 
499     @Test
500     public void whereTestParentheses() {
501         String statement = "SELECT p1 FROM MyType WHERE (p1 IS NULL OR SCORE()=100) AND (p2=123 OR p3=456)";
502         checkTreeWhere(statement);
503     }
504 
505     @Test
506     public void doubleFromTest() {
507         String statement = "SELECT * FROM MyType JOIN YourType WHERE a='1'";
508 
509         CmisQueryWalker walker = traverseStatementAndCatchExc(statement);
510         assertNotNull(walker);
511 
512         QueryObject from = queryObj;
513         Map<String,String> types = from.getTypes();
514         assertTrue(2 == types.size());
515     }
516 
517     @Test
518     public void duplicatedAliasTestSelect() {
519         String statement = "SELECT p1.T1 MyAlias, p2.T1 AS MyAlias FROM T1";
520         try {
521             traverseStatement(statement);
522         } catch (Exception e) {
523             assertTrue(e.getMessage().contains("more than once as alias in a select"));
524         }
525     }
526 
527     @Test
528     public void duplicatedAliasTestFrom() {
529         String statement = "SELECT * FROM T1 MyAlias JOIN T2 AS MyAlias";
530         try {
531             traverseStatement(statement);
532             fail("Parsing statement " + statement + " should fail.");
533         } catch (RecognitionException e) {
534             assertTrue(e instanceof FailedPredicateException);
535             LOG.debug("duplicatedAliasTestFrom(), exception: " + e);
536             // walker.reportError(e);
537             String errorMessage = queryUtil.getErrorMessage(e);
538             LOG.debug("");
539             LOG.debug("duplicatedAliasTestFrom(), error message: " + errorMessage);
540             assertTrue(e.toString().contains("more than once as alias in a from"));
541             assertTrue(errorMessage.contains("more than once as alias in a from"));
542         } catch (Exception e) {
543             fail("Parsing statement " + statement + " should fail with RecognitionException, but was: " + e.getClass());
544         }
545     }
546     
547     @Test
548     public void whereTestContains2() {
549         String statement = "SELECT p1 FROM MyType WHERE CONTAINS('Beethoven OR \\'Johann Sebastian\\' Mozart -Cage AND Orff')";
550         checkTreeWhere(statement);
551         Tree tree = findSearchExpression(statement);
552         printSearchTree(tree, statement);
553     }
554     
555     private void checkTreeWhere(String statement) {
556         LOG.info("\ncheckTreeWhere: " + statement);
557         traverseStatementAndCatchExc(statement);
558         Tree whereTree = walker.getWherePredicateTree();
559         evalWhereTree(whereTree);
560     }
561     
562     private Tree findSearchExpression(String statement) {
563         traverseStatementAndCatchExc(statement);
564         Tree whereTree = walker.getWherePredicateTree(); 
565         return findTextSearchNode(whereTree);
566     }
567     
568     private Tree findTextSearchNode(Tree node) {
569         int count = node.getChildCount();
570         if (node.getType() == CmisQlStrictLexer.CONTAINS) {
571             return node;
572         } else {
573             for (int i=0; i<count; i++) {
574                 Tree child = node.getChild(i);
575                 node = findTextSearchNode(child); // recursive descent
576                 if (null != node)
577                     return node;
578             }
579             return null;
580         }        
581     }
582 
583     private void evalWhereTree(Tree root) {
584         int count = root.getChildCount();
585         if (root.getType() == CmisQlStrictLexer.CONTAINS) {
586             evalSearchExprTree(root);
587         } else {
588             for (int i=0; i<count; i++) {
589                 Tree child = root.getChild(i);
590                 evaluateWhereNode(child);
591                 evalWhereTree(child); // recursive descent
592             }
593         }
594     }
595     
596     private void evalSearchExprTree(Tree root) {
597         int count = root.getChildCount();
598         for (int i=0; i<count; i++) {
599             Tree child = root.getChild(i);
600             evaluateSearchExprNode(child);
601             evalSearchExprTree(child); // recursive descent
602         }
603     }
604     
605     private void printTree(Tree tree, String statement) {
606         LOG.info("Printing the abstract syntax tree for statement:");
607         LOG.info("  " + statement);
608         printTree(tree);
609     }
610 
611     private int indent = 1;
612 
613     private String indentString() {
614         StringBuffer sb = new StringBuffer();
615         for (int i = 0; i < indent; ++i) {
616             sb.append("  ");
617         }
618         return sb.toString();
619     }
620 
621     private void printTree(Tree node) {
622         LOG.info(indentString() + printNode(node));
623         ++indent;
624         int count = node.getChildCount();
625         for (int i=0;i<count;i++) {
626             Tree child = node.getChild(i);
627             printTree(child);
628         }
629         --indent;
630     }
631 
632     private static String printNode(Tree node) {
633         switch (node.getType()) {
634         case CmisQlStrictLexer.TABLE:
635             return "#TABLE";
636         case CmisQlStrictLexer.COL:
637             return "#COL";
638         case CmisQlStrictLexer.IN_LIST:
639             return "#IN_LIST";
640         case CmisQlStrictLexer.SEL_LIST:
641             return "#SEL_LIST";
642         case CmisQlStrictLexer.EQ_ANY:
643             return "#EQ_ANY";
644         case CmisQlStrictLexer.NOT_LIKE:
645             return "#NOT_LIKE";
646         case CmisQlStrictLexer.NOT_IN:
647             return "#NOT_IN";
648         case CmisQlStrictLexer.IN_ANY:
649             return "#IN_ANY";
650         case CmisQlStrictLexer.NOT_IN_ANY:
651             return "#NOT_IN_ANY";
652         case CmisQlStrictLexer.IS_NULL:
653             return "#IS_NULL";
654         case CmisQlStrictLexer.IS_NOT_NULL:
655             return "#IS_NOT_NULL";
656         case CmisQlStrictLexer.ORDER_BY:
657             return "#ORDER_BY";
658 
659         case CmisQlStrictLexer.WHERE:
660         case CmisQlStrictLexer.LT:
661         case CmisQlStrictLexer.STAR:
662         case CmisQlStrictLexer.BOOL_LIT:
663         case CmisQlStrictLexer.INNER:
664         case CmisQlStrictLexer.TIME_LIT:
665         case CmisQlStrictLexer.ORDER:
666         case CmisQlStrictLexer.STRING_LIT:
667         case CmisQlStrictLexer.CONTAINS:
668         case CmisQlStrictLexer.ExactNumLit:
669         case CmisQlStrictLexer.LTEQ:
670         case CmisQlStrictLexer.NOT:
671         case CmisQlStrictLexer.ID:
672         case CmisQlStrictLexer.AND:
673         case CmisQlStrictLexer.EOF:
674         case CmisQlStrictLexer.AS:
675         case CmisQlStrictLexer.IN:
676         case CmisQlStrictLexer.LPAR:
677         case CmisQlStrictLexer.Digits:
678         case CmisQlStrictLexer.COMMA:
679         case CmisQlStrictLexer.IS:
680         case CmisQlStrictLexer.LEFT:
681         case CmisQlStrictLexer.Sign:
682         case CmisQlStrictLexer.EQ:
683         case CmisQlStrictLexer.DOT:
684         case CmisQlStrictLexer.NUM_LIT:
685         case CmisQlStrictLexer.SELECT:
686         case CmisQlStrictLexer.LIKE:
687         case CmisQlStrictLexer.OUTER:
688         case CmisQlStrictLexer.BY:
689         case CmisQlStrictLexer.ASC:
690         case CmisQlStrictLexer.NULL:
691         case CmisQlStrictLexer.ON:
692         case CmisQlStrictLexer.RIGHT:
693         case CmisQlStrictLexer.GTEQ:
694         case CmisQlStrictLexer.ApproxNumLit:
695         case CmisQlStrictLexer.JOIN:
696         case CmisQlStrictLexer.IN_FOLDER:
697         case CmisQlStrictLexer.WS:
698         case CmisQlStrictLexer.NEQ:
699         case CmisQlStrictLexer.ANY:
700         case CmisQlStrictLexer.SCORE:
701         case CmisQlStrictLexer.IN_TREE:
702         case CmisQlStrictLexer.OR:
703         case CmisQlStrictLexer.GT:
704         case CmisQlStrictLexer.RPAR:
705         case CmisQlStrictLexer.DESC:
706         case CmisQlStrictLexer.FROM:
707         case CmisQlStrictLexer.TIMESTAMP:
708             return node.toString();
709         default:
710             return "[Unknown token: " + node.toString() + "]";
711         }
712     }
713 
714     private void printSearchTree(Tree tree, String searchExpr) {
715         LOG.info("Printhing the abstract syntax tree for the search expression in CONTAINS :");
716         LOG.info(searchExpr);
717         printSearchTree(tree);
718     }
719 
720     private void printSearchTree(Tree node) {
721         LOG.info(indentString() + printSearchNode(node));
722         ++indent;
723         int count = node.getChildCount();
724         for (int i=0;i<count;i++) {
725             Tree child = node.getChild(i);
726             printSearchTree(child);
727         }
728         --indent;
729     }
730 
731     private static String printSearchNode(Tree node) {
732         switch (node.getType()) {
733         case TextSearchLexer.TEXT_AND:
734         case TextSearchLexer.TEXT_OR:
735         case TextSearchLexer.TEXT_SEARCH_PHRASE_STRING_LIT:
736         case TextSearchLexer.TEXT_SEARCH_WORD_LIT:            
737             return node.toString();
738         case TextSearchLexer.TEXT_MINUS:
739             return "MINUS";
740          default:
741              return "Unknown token: " +  node.toString();
742         }
743     }
744     
745     // Ensure that we receive only valid tokens and nodes in the where clause:
746     private void evaluateWhereNode(Tree node) {
747         LOG.info("evaluating node: " + node.toString());
748         switch (node.getType()) {
749         case CmisQlStrictLexer.WHERE:
750             break; // ignore
751         case CmisQlStrictLexer.COL:
752             evalColumn(node);
753             break;
754         case CmisQlStrictLexer.IN_LIST:
755             evalInList(node);
756             break;
757         case CmisQlStrictLexer.IN_ANY:
758             evalInAny(node);
759             break;
760         case CmisQlStrictLexer.EQ_ANY:
761             evalEqAny(node);
762             break;
763         case CmisQlStrictLexer.NOT_LIKE:
764             evalNotLike(node);
765             break;
766         case CmisQlStrictLexer.NOT_IN:
767             evalNotIn(node);
768             break;
769         case CmisQlStrictLexer.IS_NULL:
770             evalIsNull(node);
771             break;
772         case CmisQlStrictLexer.IS_NOT_NULL:
773             evalIsNotNull(node);
774             break;
775         case CmisQlStrictLexer.LT:
776             evalLessThan(node);
777             break;
778         case CmisQlStrictLexer.BOOL_LIT:
779             evalBooleanLiteral(node);
780             break;
781         case CmisQlStrictLexer.TIME_LIT:
782             evalTimeLiteral(node);
783             break;
784         case CmisQlStrictLexer.STRING_LIT:
785             evalStringLiteral(node);
786             break;
787         case CmisQlStrictLexer.CONTAINS:
788             evalContains(node);
789             break;
790         case CmisQlStrictLexer.ExactNumLit:
791             evalExactNumLiteral(node);
792             break;
793         case CmisQlStrictLexer.LTEQ:
794             evalLessOrEqual(node);
795             break;
796         case CmisQlStrictLexer.NOT:
797             evalNot(node);
798             break;
799         case CmisQlStrictLexer.ID:
800             evalId(node);
801             break;
802         case CmisQlStrictLexer.AND:
803             evalAnd(node);
804             break;
805         case CmisQlStrictLexer.IN:
806             evalIn(node);
807             break;
808         case CmisQlStrictLexer.EQ:
809             evalEquals(node);
810             break;
811         case CmisQlStrictLexer.NUM_LIT:
812             evalNumLiteral(node);
813             break;
814         case CmisQlStrictLexer.LIKE:
815             evalLike(node);
816             break;
817         case CmisQlStrictLexer.NULL:
818             evalNull(node);
819             break;
820         case CmisQlStrictLexer.GTEQ:
821             evalGreaterThan(node);
822             break;
823         case CmisQlStrictLexer.ApproxNumLit:
824             evalApproxNumLiteral(node);
825             break;
826         case CmisQlStrictLexer.IN_FOLDER:
827             evalInFolder(node);
828             break;
829         case CmisQlStrictLexer.NEQ:
830             evalNotEquals(node);
831             break;
832         case CmisQlStrictLexer.SCORE:
833             evalScore(node);
834             break;
835         case CmisQlStrictLexer.IN_TREE:
836             evalInTree(node);
837             break;
838         case CmisQlStrictLexer.OR:
839             evalOr(node);
840             break;
841         case CmisQlStrictLexer.GT:
842             evalGreaterThan(node);
843             break;
844         case CmisQlStrictLexer.TIMESTAMP:
845             evalTimeLiteral(node);
846             break;
847         default:
848             fail("[Unexpected node in WHERE clause: " + node.toString() + "]");
849         }
850     }
851 
852     // Ensure that we receive only valid tokens and nodes in the where clause:
853     private void evaluateSearchExprNode(Tree node) {
854         LOG.info("evaluating text search expression node: " + node.toString());
855         switch (node.getType()) {
856         case TextSearchLexer.TEXT_AND:
857         case TextSearchLexer.TEXT_OR:
858             assertTrue(node.getChildCount() >= 2 );
859             break;
860         case TextSearchLexer.TEXT_MINUS:
861             assertEquals(1, node.getChildCount());
862             break;
863         case TextSearchLexer.TEXT_SEARCH_PHRASE_STRING_LIT:
864         case TextSearchLexer.TEXT_SEARCH_WORD_LIT:
865             evalStringLiteral(node);
866             break;
867         default:
868             fail("[Unexpected node in text search expression: " + node.toString() + "]");         
869         }
870     }
871         
872     private void evalInAny(Tree node) {
873     }
874 
875     private static void evalColumn(Tree node) {
876         assertEquals(1, node.getChildCount());
877         assertEquals(CmisQlStrictLexer.ID, node.getChild(0).getType());
878     }
879 
880     private static void evalEquals(Tree node) {
881         assertEquals(2, node.getChildCount());
882     }
883 
884     private static void evalInFolder(Tree node) {
885         assertEquals(1, node.getChildCount());
886     }
887 
888     private static void evalApproxNumLiteral(Tree node) {
889     }
890 
891     private static void evalNull(Tree node) {
892         assertEquals(1, node.getChildCount());
893     }
894 
895     private static void evalLike(Tree node) {
896         assertEquals(2, node.getChildCount());
897     }
898 
899     private static void evalNumLiteral(Tree node) {
900         assertEquals(0, node.getChildCount());
901     }
902 
903     private static void evalInList(Tree node) {
904     }
905 
906     private static void evalEqAny(Tree node) {
907     }
908 
909     private static void evalNotLike(Tree node) {
910         assertEquals(2, node.getChildCount());
911     }
912 
913     private static void evalNotIn(Tree node) {
914     }
915 
916     private static void evalIsNull(Tree node) {
917         assertEquals(1, node.getChildCount());
918     }
919 
920     private static void evalIsNotNull(Tree node) {
921         assertEquals(1, node.getChildCount());
922     }
923 
924     private static void evalLessThan(Tree node) {
925         assertEquals(2, node.getChildCount());
926     }
927 
928     private static void evalBooleanLiteral(Tree node) {
929         assertEquals(0, node.getChildCount());
930     }
931 
932     private static void evalStringLiteral(Tree node) {
933         assertEquals(0, node.getChildCount());
934     }
935 
936     private static void evalContains(Tree node) {
937         assertEquals(1, node.getChildCount());
938     }
939 
940     private static void evalExactNumLiteral(Tree node) {
941         assertEquals(0, node.getChildCount());
942     }
943 
944     private static void evalLessOrEqual(Tree node) {
945         assertEquals(2, node.getChildCount());
946     }
947 
948     private static void evalNot(Tree node) {
949         assertEquals(1, node.getChildCount());
950     }
951 
952     private static void evalId(Tree node) {
953         assertEquals(0, node.getChildCount());
954     }
955 
956     private static void evalAnd(Tree node) {
957         assertEquals(2, node.getChildCount());
958     }
959 
960     private void evalIn(Tree node) {
961     }
962 
963     private static void evalNotEquals(Tree node) {
964         assertEquals(2, node.getChildCount());
965     }
966 
967     private static void evalScore(Tree node) {
968         assertEquals(0, node.getChildCount());
969     }
970 
971     private static void evalInTree(Tree node) {
972         assertEquals(1, node.getChildCount());
973     }
974 
975     private static void evalOr(Tree node) {
976         assertEquals(2, node.getChildCount());
977     }
978 
979     private static void evalGreaterThan(Tree node) {
980         assertEquals(2, node.getChildCount());
981     }
982 
983     private static void evalTimeLiteral(Tree node) {
984         assertEquals(0, node.getChildCount());
985     }
986 
987 }