1 package org.apache.lucene.queryParser.standard;
4 * Licensed to the Apache Software Foundation (ASF) under one or more
5 * contributor license agreements. See the NOTICE file distributed with
6 * this work for additional information regarding copyright ownership.
7 * The ASF licenses this file to You under the Apache License, Version 2.0
8 * (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
20 import java.io.IOException;
21 import java.io.Reader;
22 import java.text.Collator;
23 import java.text.DateFormat;
24 import java.util.Calendar;
25 import java.util.Date;
26 import java.util.GregorianCalendar;
27 import java.util.List;
28 import java.util.Locale;
29 import java.util.Collections;
31 import org.apache.lucene.analysis.Analyzer;
32 import org.apache.lucene.analysis.KeywordAnalyzer;
33 import org.apache.lucene.analysis.LowerCaseTokenizer;
34 import org.apache.lucene.analysis.SimpleAnalyzer;
35 import org.apache.lucene.analysis.StopAnalyzer;
36 import org.apache.lucene.analysis.StopFilter;
37 import org.apache.lucene.analysis.TokenFilter;
38 import org.apache.lucene.analysis.TokenStream;
39 import org.apache.lucene.analysis.WhitespaceAnalyzer;
40 import org.apache.lucene.analysis.standard.StandardAnalyzer;
41 import org.apache.lucene.analysis.tokenattributes.OffsetAttribute;
42 import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
43 import org.apache.lucene.document.DateField;
44 import org.apache.lucene.document.DateTools;
45 import org.apache.lucene.document.Document;
46 import org.apache.lucene.document.Field;
47 import org.apache.lucene.index.IndexWriter;
48 import org.apache.lucene.index.Term;
49 import org.apache.lucene.messages.MessageImpl;
50 import org.apache.lucene.queryParser.ParseException;
51 import org.apache.lucene.queryParser.core.QueryNodeException;
52 import org.apache.lucene.queryParser.core.messages.QueryParserMessages;
53 import org.apache.lucene.queryParser.core.nodes.FuzzyQueryNode;
54 import org.apache.lucene.queryParser.core.nodes.QueryNode;
55 import org.apache.lucene.queryParser.core.processors.QueryNodeProcessorImpl;
56 import org.apache.lucene.queryParser.core.processors.QueryNodeProcessorPipeline;
57 import org.apache.lucene.queryParser.standard.nodes.WildcardQueryNode;
58 import org.apache.lucene.queryParser.standard.processors.WildcardQueryNodeProcessor;
59 import org.apache.lucene.search.BooleanClause;
60 import org.apache.lucene.search.BooleanQuery;
61 import org.apache.lucene.search.FuzzyQuery;
62 import org.apache.lucene.search.IndexSearcher;
63 import org.apache.lucene.search.MatchAllDocsQuery;
64 import org.apache.lucene.search.MultiTermQuery;
65 import org.apache.lucene.search.PhraseQuery;
66 import org.apache.lucene.search.PrefixQuery;
67 import org.apache.lucene.search.Query;
68 import org.apache.lucene.search.ScoreDoc;
69 import org.apache.lucene.search.TermQuery;
70 import org.apache.lucene.search.TermRangeQuery;
71 import org.apache.lucene.search.WildcardQuery;
72 import org.apache.lucene.store.Directory;
73 import org.apache.lucene.util.LuceneTestCase;
76 * This test case is a copy of the core Lucene query parser test, it was adapted
77 * to use new {@link QueryParserWrapper} instead of the old query parser.
81 * @deprecated this entire test case tests QueryParserWrapper which is
82 * deprecated. When QPW is gone, so will the test.
85 public class TestQueryParserWrapper extends LuceneTestCase {
87 public static Analyzer qpAnalyzer = new QPTestAnalyzer();
89 public static final class QPTestFilter extends TokenFilter {
90 private final CharTermAttribute termAtt = addAttribute(CharTermAttribute.class);
91 private final OffsetAttribute offsetAtt = addAttribute(OffsetAttribute.class);
94 * Filter which discards the token 'stop' and which expands the token
95 * 'phrase' into 'phrase1 phrase2'
97 public QPTestFilter(TokenStream in) {
101 boolean inPhrase = false;
102 int savedStart = 0, savedEnd = 0;
105 public boolean incrementToken() throws IOException {
109 termAtt.setEmpty().append("phrase2");
110 offsetAtt.setOffset(savedStart, savedEnd);
113 while (input.incrementToken()) {
114 if (termAtt.toString().equals("phrase")) {
116 savedStart = offsetAtt.startOffset();
117 savedEnd = offsetAtt.endOffset();
118 termAtt.setEmpty().append("phrase1");
119 offsetAtt.setOffset(savedStart, savedEnd);
121 } else if (!termAtt.toString().equals("stop"))
128 public static final class QPTestAnalyzer extends Analyzer {
130 /** Filters LowerCaseTokenizer with StopFilter. */
132 public final TokenStream tokenStream(String fieldName, Reader reader) {
133 return new QPTestFilter(new LowerCaseTokenizer(TEST_VERSION_CURRENT, reader));
137 public static class QPTestParser extends QueryParserWrapper {
138 public QPTestParser(String f, Analyzer a) {
141 QueryNodeProcessorPipeline newProcessorPipeline = new QueryNodeProcessorPipeline(
142 getQueryProcessor().getQueryConfigHandler());
143 newProcessorPipeline.add(new WildcardQueryNodeProcessor());
144 newProcessorPipeline.add(new QPTestParserQueryNodeProcessor());
145 newProcessorPipeline.add(getQueryProcessor());
147 setQueryProcessor(newProcessorPipeline);
152 protected Query getFuzzyQuery(String field, String termStr,
153 float minSimilarity) throws ParseException {
154 throw new ParseException("Fuzzy queries not allowed");
158 protected Query getWildcardQuery(String field, String termStr)
159 throws ParseException {
160 throw new ParseException("Wildcard queries not allowed");
163 private static class QPTestParserQueryNodeProcessor extends
164 QueryNodeProcessorImpl {
167 protected QueryNode postProcessNode(QueryNode node)
168 throws QueryNodeException {
175 protected QueryNode preProcessNode(QueryNode node)
176 throws QueryNodeException {
178 if (node instanceof WildcardQueryNode || node instanceof FuzzyQueryNode) {
180 throw new QueryNodeException(new MessageImpl(
181 QueryParserMessages.EMPTY_MESSAGE));
190 protected List<QueryNode> setChildrenOrder(List<QueryNode> children)
191 throws QueryNodeException {
201 private int originalMaxClauses;
204 public void setUp() throws Exception {
206 originalMaxClauses = BooleanQuery.getMaxClauseCount();
209 public QueryParserWrapper getParser(Analyzer a) throws Exception {
211 a = new SimpleAnalyzer(TEST_VERSION_CURRENT);
212 QueryParserWrapper qp = new QueryParserWrapper("field", a);
213 qp.setDefaultOperator(QueryParserWrapper.OR_OPERATOR);
217 public Query getQuery(String query, Analyzer a) throws Exception {
218 return getParser(a).parse(query);
221 public Query getQueryAllowLeadingWildcard(String query, Analyzer a) throws Exception {
222 QueryParserWrapper parser = getParser(a);
223 parser.setAllowLeadingWildcard(true);
224 return parser.parse(query);
227 public void assertQueryEquals(String query, Analyzer a, String result)
229 Query q = getQuery(query, a);
230 String s = q.toString("field");
231 if (!s.equals(result)) {
232 fail("Query /" + query + "/ yielded /" + s + "/, expecting /" + result
237 public void assertQueryEqualsAllowLeadingWildcard(String query, Analyzer a, String result)
239 Query q = getQueryAllowLeadingWildcard(query, a);
240 String s = q.toString("field");
241 if (!s.equals(result)) {
242 fail("Query /" + query + "/ yielded /" + s + "/, expecting /" + result
246 public void assertQueryEquals(QueryParserWrapper qp, String field,
247 String query, String result) throws Exception {
248 Query q = qp.parse(query);
249 String s = q.toString(field);
250 if (!s.equals(result)) {
251 fail("Query /" + query + "/ yielded /" + s + "/, expecting /" + result
256 public void assertEscapedQueryEquals(String query, Analyzer a, String result)
258 String escapedQuery = QueryParserWrapper.escape(query);
259 if (!escapedQuery.equals(result)) {
260 fail("Query /" + query + "/ yielded /" + escapedQuery + "/, expecting /"
265 public void assertWildcardQueryEquals(String query, boolean lowercase,
266 String result, boolean allowLeadingWildcard) throws Exception {
267 QueryParserWrapper qp = getParser(null);
268 qp.setLowercaseExpandedTerms(lowercase);
269 qp.setAllowLeadingWildcard(allowLeadingWildcard);
270 Query q = qp.parse(query);
271 String s = q.toString("field");
272 if (!s.equals(result)) {
273 fail("WildcardQuery /" + query + "/ yielded /" + s + "/, expecting /"
278 public void assertWildcardQueryEquals(String query, boolean lowercase,
279 String result) throws Exception {
280 assertWildcardQueryEquals(query, lowercase, result, false);
283 public void assertWildcardQueryEquals(String query, String result)
285 QueryParserWrapper qp = getParser(null);
286 Query q = qp.parse(query);
287 String s = q.toString("field");
288 if (!s.equals(result)) {
289 fail("WildcardQuery /" + query + "/ yielded /" + s + "/, expecting /"
294 public Query getQueryDOA(String query, Analyzer a) throws Exception {
296 a = new SimpleAnalyzer(TEST_VERSION_CURRENT);
297 QueryParserWrapper qp = new QueryParserWrapper("field", a);
298 qp.setDefaultOperator(QueryParserWrapper.AND_OPERATOR);
299 return qp.parse(query);
302 public void assertQueryEqualsDOA(String query, Analyzer a, String result)
304 Query q = getQueryDOA(query, a);
305 String s = q.toString("field");
306 if (!s.equals(result)) {
307 fail("Query /" + query + "/ yielded /" + s + "/, expecting /" + result
312 public void testCJK() throws Exception {
313 // Test Ideographic Space - As wide as a CJK character cell (fullwidth)
314 // used google to translate the word "term" to japanese -> ??
315 assertQueryEquals("term\u3000term\u3000term", null,
316 "term\u0020term\u0020term");
317 assertQueryEqualsAllowLeadingWildcard("??\u3000??\u3000??", null, "??\u0020??\u0020??");
320 public void testCJKTerm() throws Exception {
321 // individual CJK chars as terms
322 StandardAnalyzer analyzer = new StandardAnalyzer(TEST_VERSION_CURRENT);
324 BooleanQuery expected = new BooleanQuery();
325 expected.add(new TermQuery(new Term("field", "ä¸")), BooleanClause.Occur.SHOULD);
326 expected.add(new TermQuery(new Term("field", "国")), BooleanClause.Occur.SHOULD);
328 assertEquals(expected, getQuery("ä¸å›½", analyzer));
331 public void testCJKBoostedTerm() throws Exception {
332 // individual CJK chars as terms
333 StandardAnalyzer analyzer = new StandardAnalyzer(TEST_VERSION_CURRENT);
335 BooleanQuery expected = new BooleanQuery();
336 expected.setBoost(0.5f);
337 expected.add(new TermQuery(new Term("field", "ä¸")), BooleanClause.Occur.SHOULD);
338 expected.add(new TermQuery(new Term("field", "国")), BooleanClause.Occur.SHOULD);
340 assertEquals(expected, getQuery("ä¸å›½^0.5", analyzer));
343 public void testCJKPhrase() throws Exception {
344 // individual CJK chars as terms
345 StandardAnalyzer analyzer = new StandardAnalyzer(TEST_VERSION_CURRENT);
347 PhraseQuery expected = new PhraseQuery();
348 expected.add(new Term("field", "ä¸"));
349 expected.add(new Term("field", "国"));
351 assertEquals(expected, getQuery("\"ä¸å›½\"", analyzer));
354 public void testCJKBoostedPhrase() throws Exception {
355 // individual CJK chars as terms
356 StandardAnalyzer analyzer = new StandardAnalyzer(TEST_VERSION_CURRENT);
358 PhraseQuery expected = new PhraseQuery();
359 expected.setBoost(0.5f);
360 expected.add(new Term("field", "ä¸"));
361 expected.add(new Term("field", "国"));
363 assertEquals(expected, getQuery("\"ä¸å›½\"^0.5", analyzer));
366 public void testCJKSloppyPhrase() throws Exception {
367 // individual CJK chars as terms
368 StandardAnalyzer analyzer = new StandardAnalyzer(TEST_VERSION_CURRENT);
370 PhraseQuery expected = new PhraseQuery();
372 expected.add(new Term("field", "ä¸"));
373 expected.add(new Term("field", "国"));
375 assertEquals(expected, getQuery("\"ä¸å›½\"~3", analyzer));
378 public void testSimple() throws Exception {
379 assertQueryEquals("\"term germ\"~2", null, "\"term germ\"~2");
380 assertQueryEquals("term term term", null, "term term term");
381 assertQueryEquals("t�rm term term", new WhitespaceAnalyzer(TEST_VERSION_CURRENT),
383 assertQueryEquals("�mlaut", new WhitespaceAnalyzer(TEST_VERSION_CURRENT), "�mlaut");
385 assertQueryEquals("\"\"", new KeywordAnalyzer(), "");
386 assertQueryEquals("foo:\"\"", new KeywordAnalyzer(), "foo:");
388 assertQueryEquals("a AND b", null, "+a +b");
389 assertQueryEquals("(a AND b)", null, "+a +b");
390 assertQueryEquals("c OR (a AND b)", null, "c (+a +b)");
392 assertQueryEquals("a AND NOT b", null, "+a -b");
394 assertQueryEquals("a AND -b", null, "+a -b");
396 assertQueryEquals("a AND !b", null, "+a -b");
398 assertQueryEquals("a && b", null, "+a +b");
400 assertQueryEquals("a && ! b", null, "+a -b");
402 assertQueryEquals("a OR b", null, "a b");
403 assertQueryEquals("a || b", null, "a b");
405 assertQueryEquals("a OR !b", null, "a -b");
407 assertQueryEquals("a OR ! b", null, "a -b");
409 assertQueryEquals("a OR -b", null, "a -b");
411 assertQueryEquals("+term -term term", null, "+term -term term");
412 assertQueryEquals("foo:term AND field:anotherTerm", null,
413 "+foo:term +anotherterm");
414 assertQueryEquals("term AND \"phrase phrase\"", null,
415 "+term +\"phrase phrase\"");
416 assertQueryEquals("\"hello there\"", null, "\"hello there\"");
417 assertTrue(getQuery("a AND b", null) instanceof BooleanQuery);
418 assertTrue(getQuery("hello", null) instanceof TermQuery);
419 assertTrue(getQuery("\"hello there\"", null) instanceof PhraseQuery);
421 assertQueryEquals("germ term^2.0", null, "germ term^2.0");
422 assertQueryEquals("(term)^2.0", null, "term^2.0");
423 assertQueryEquals("(germ term)^2.0", null, "(germ term)^2.0");
424 assertQueryEquals("term^2.0", null, "term^2.0");
425 assertQueryEquals("term^2", null, "term^2.0");
426 assertQueryEquals("\"germ term\"^2.0", null, "\"germ term\"^2.0");
427 assertQueryEquals("\"term germ\"^2", null, "\"term germ\"^2.0");
429 assertQueryEquals("(foo OR bar) AND (baz OR boo)", null,
430 "+(foo bar) +(baz boo)");
431 assertQueryEquals("((a OR b) AND NOT c) OR d", null, "(+(a b) -c) d");
432 assertQueryEquals("+(apple \"steve jobs\") -(foo bar baz)", null,
433 "+(apple \"steve jobs\") -(foo bar baz)");
434 assertQueryEquals("+title:(dog OR cat) -author:\"bob dole\"", null,
435 "+(title:dog title:cat) -author:\"bob dole\"");
437 QueryParserWrapper qp = new QueryParserWrapper("field",
438 new StandardAnalyzer(TEST_VERSION_CURRENT));
439 // make sure OR is the default:
440 assertEquals(QueryParserWrapper.OR_OPERATOR, qp.getDefaultOperator());
441 qp.setDefaultOperator(QueryParserWrapper.AND_OPERATOR);
442 assertEquals(QueryParserWrapper.AND_OPERATOR, qp.getDefaultOperator());
443 qp.setDefaultOperator(QueryParserWrapper.OR_OPERATOR);
444 assertEquals(QueryParserWrapper.OR_OPERATOR, qp.getDefaultOperator());
447 public void testPunct() throws Exception {
448 Analyzer a = new WhitespaceAnalyzer(TEST_VERSION_CURRENT);
449 assertQueryEquals("a&b", a, "a&b");
450 assertQueryEquals("a&&b", a, "a&&b");
451 assertQueryEquals(".NET", a, ".NET");
454 public void testSlop() throws Exception {
456 assertQueryEquals("\"term germ\"~2", null, "\"term germ\"~2");
457 assertQueryEquals("\"term germ\"~2 flork", null, "\"term germ\"~2 flork");
458 assertQueryEquals("\"term\"~2", null, "term");
459 assertQueryEquals("\" \"~2 germ", null, "germ");
460 assertQueryEquals("\"term germ\"~2^2", null, "\"term germ\"~2^2.0");
463 public void testNumber() throws Exception {
464 // The numbers go away because SimpleAnalzyer ignores them
465 assertQueryEquals("3", null, "");
466 assertQueryEquals("term 1.0 1 2", null, "term");
467 assertQueryEquals("term term1 term2", null, "term term term");
469 Analyzer a = new StandardAnalyzer(TEST_VERSION_CURRENT);
470 assertQueryEquals("3", a, "3");
471 assertQueryEquals("term 1.0 1 2", a, "term 1.0 1 2");
472 assertQueryEquals("term term1 term2", a, "term term1 term2");
475 public void testWildcard() throws Exception {
476 assertQueryEquals("term*", null, "term*");
477 assertQueryEquals("term*^2", null, "term*^2.0");
478 assertQueryEquals("term~", null, "term~0.5");
479 assertQueryEquals("term~0.7", null, "term~0.7");
481 assertQueryEquals("term~^2", null, "term~0.5^2.0");
483 assertQueryEquals("term^2~", null, "term~0.5^2.0");
484 assertQueryEquals("term*germ", null, "term*germ");
485 assertQueryEquals("term*germ^3", null, "term*germ^3.0");
487 assertTrue(getQuery("term*", null) instanceof PrefixQuery);
488 assertTrue(getQuery("term*^2", null) instanceof PrefixQuery);
489 assertTrue(getQuery("term~", null) instanceof FuzzyQuery);
490 assertTrue(getQuery("term~0.7", null) instanceof FuzzyQuery);
491 FuzzyQuery fq = (FuzzyQuery) getQuery("term~0.7", null);
492 assertEquals(0.7f, fq.getMinSimilarity(), 0.1f);
493 assertEquals(FuzzyQuery.defaultPrefixLength, fq.getPrefixLength());
494 fq = (FuzzyQuery) getQuery("term~", null);
495 assertEquals(0.5f, fq.getMinSimilarity(), 0.1f);
496 assertEquals(FuzzyQuery.defaultPrefixLength, fq.getPrefixLength());
498 assertParseException("term~1.1"); // value > 1, throws exception
500 assertTrue(getQuery("term*germ", null) instanceof WildcardQuery);
503 * Tests to see that wild card terms are (or are not) properly lower-cased
504 * with propery parser configuration
506 // First prefix queries:
507 // by default, convert to lowercase:
508 assertWildcardQueryEquals("Term*", true, "term*");
509 // explicitly set lowercase:
510 assertWildcardQueryEquals("term*", true, "term*");
511 assertWildcardQueryEquals("Term*", true, "term*");
512 assertWildcardQueryEquals("TERM*", true, "term*");
513 // explicitly disable lowercase conversion:
514 assertWildcardQueryEquals("term*", false, "term*");
515 assertWildcardQueryEquals("Term*", false, "Term*");
516 assertWildcardQueryEquals("TERM*", false, "TERM*");
517 // Then 'full' wildcard queries:
518 // by default, convert to lowercase:
519 assertWildcardQueryEquals("Te?m", "te?m");
520 // explicitly set lowercase:
521 assertWildcardQueryEquals("te?m", true, "te?m");
522 assertWildcardQueryEquals("Te?m", true, "te?m");
523 assertWildcardQueryEquals("TE?M", true, "te?m");
524 assertWildcardQueryEquals("Te?m*gerM", true, "te?m*germ");
525 // explicitly disable lowercase conversion:
526 assertWildcardQueryEquals("te?m", false, "te?m");
527 assertWildcardQueryEquals("Te?m", false, "Te?m");
528 assertWildcardQueryEquals("TE?M", false, "TE?M");
529 assertWildcardQueryEquals("Te?m*gerM", false, "Te?m*gerM");
531 assertWildcardQueryEquals("Term~", "term~0.5");
532 assertWildcardQueryEquals("Term~", true, "term~0.5");
533 assertWildcardQueryEquals("Term~", false, "Term~0.5");
536 // TODO: implement this on QueryParser
537 // Q0002E_INVALID_SYNTAX_CANNOT_PARSE: Syntax Error, cannot parse '[A TO
538 // C]': Lexical error at line 1, column 1. Encountered: "[" (91), after : ""
539 assertWildcardQueryEquals("[A TO C]", "[a TO c]");
540 assertWildcardQueryEquals("[A TO C]", true, "[a TO c]");
541 assertWildcardQueryEquals("[A TO C]", false, "[A TO C]");
542 // Test suffix queries: first disallow
544 assertWildcardQueryEquals("*Term", true, "*term");
546 } catch (ParseException pe) {
547 // expected exception
550 assertWildcardQueryEquals("?Term", true, "?term");
552 } catch (ParseException pe) {
553 // expected exception
555 // Test suffix queries: then allow
556 assertWildcardQueryEquals("*Term", true, "*term", true);
557 assertWildcardQueryEquals("?Term", true, "?term", true);
560 public void testLeadingWildcardType() throws Exception {
561 QueryParserWrapper qp = getParser(null);
562 qp.setAllowLeadingWildcard(true);
563 assertEquals(WildcardQuery.class, qp.parse("t*erm*").getClass());
564 assertEquals(WildcardQuery.class, qp.parse("?term*").getClass());
565 assertEquals(WildcardQuery.class, qp.parse("*term*").getClass());
568 public void testQPA() throws Exception {
569 assertQueryEquals("term term^3.0 term", qpAnalyzer, "term term^3.0 term");
570 assertQueryEquals("term stop^3.0 term", qpAnalyzer, "term term");
572 assertQueryEquals("term term term", qpAnalyzer, "term term term");
573 assertQueryEquals("term +stop term", qpAnalyzer, "term term");
574 assertQueryEquals("term -stop term", qpAnalyzer, "term term");
576 assertQueryEquals("drop AND (stop) AND roll", qpAnalyzer, "+drop +roll");
577 assertQueryEquals("term +(stop) term", qpAnalyzer, "term term");
578 assertQueryEquals("term -(stop) term", qpAnalyzer, "term term");
580 assertQueryEquals("drop AND stop AND roll", qpAnalyzer, "+drop +roll");
581 assertQueryEquals("term phrase term", qpAnalyzer,
582 "term phrase1 phrase2 term");
584 assertQueryEquals("term AND NOT phrase term", qpAnalyzer,
585 "+term -(phrase1 phrase2) term");
587 assertQueryEquals("stop^3", qpAnalyzer, "");
588 assertQueryEquals("stop", qpAnalyzer, "");
589 assertQueryEquals("(stop)^3", qpAnalyzer, "");
590 assertQueryEquals("((stop))^3", qpAnalyzer, "");
591 assertQueryEquals("(stop^3)", qpAnalyzer, "");
592 assertQueryEquals("((stop)^3)", qpAnalyzer, "");
593 assertQueryEquals("(stop)", qpAnalyzer, "");
594 assertQueryEquals("((stop))", qpAnalyzer, "");
595 assertTrue(getQuery("term term term", qpAnalyzer) instanceof BooleanQuery);
596 assertTrue(getQuery("term +stop", qpAnalyzer) instanceof TermQuery);
599 public void testRange() throws Exception {
600 assertQueryEquals("[ a TO z]", null, "[a TO z]");
601 assertEquals(MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT, ((TermRangeQuery)getQuery("[ a TO z]", null)).getRewriteMethod());
603 QueryParserWrapper qp = new QueryParserWrapper("field",
604 new SimpleAnalyzer(TEST_VERSION_CURRENT));
606 qp.setMultiTermRewriteMethod(MultiTermQuery.SCORING_BOOLEAN_QUERY_REWRITE);
607 assertEquals(MultiTermQuery.SCORING_BOOLEAN_QUERY_REWRITE,((TermRangeQuery)qp.parse("[ a TO z]")).getRewriteMethod());
609 assertQueryEquals("[ a TO z ]", null, "[a TO z]");
610 assertQueryEquals("{ a TO z}", null, "{a TO z}");
611 assertQueryEquals("{ a TO z }", null, "{a TO z}");
612 assertQueryEquals("{ a TO z }^2.0", null, "{a TO z}^2.0");
613 assertQueryEquals("[ a TO z] OR bar", null, "[a TO z] bar");
614 assertQueryEquals("[ a TO z] AND bar", null, "+[a TO z] +bar");
615 assertQueryEquals("( bar blar { a TO z}) ", null, "bar blar {a TO z}");
616 assertQueryEquals("gack ( bar blar { a TO z}) ", null,
617 "gack (bar blar {a TO z})");
620 public void testFarsiRangeCollating() throws Exception {
622 Directory ramDir = newDirectory();
623 IndexWriter iw = new IndexWriter(ramDir, new WhitespaceAnalyzer(TEST_VERSION_CURRENT), true,
624 IndexWriter.MaxFieldLength.LIMITED);
625 Document doc = new Document();
626 doc.add(newField("content", "\u0633\u0627\u0628", Field.Store.YES,
627 Field.Index.NOT_ANALYZED));
630 IndexSearcher is = new IndexSearcher(ramDir, true);
632 QueryParserWrapper qp = new QueryParserWrapper("content",
633 new WhitespaceAnalyzer(TEST_VERSION_CURRENT));
635 // Neither Java 1.4.2 nor 1.5.0 has Farsi Locale collation available in
636 // RuleBasedCollator. However, the Arabic Locale seems to order the Farsi
637 // characters properly.
638 Collator c = Collator.getInstance(new Locale("ar"));
639 qp.setRangeCollator(c);
641 // Unicode order would include U+0633 in [ U+062F - U+0698 ], but Farsi
642 // orders the U+0698 character before the U+0633 character, so the single
643 // index Term below should NOT be returned by a ConstantScoreRangeQuery
644 // with a Farsi Collator (or an Arabic one for the case when Farsi is not
647 // Test ConstantScoreRangeQuery
648 qp.setMultiTermRewriteMethod(MultiTermQuery.CONSTANT_SCORE_FILTER_REWRITE);
649 ScoreDoc[] result = is.search(qp.parse("[ \u062F TO \u0698 ]"), null, 1000).scoreDocs;
650 assertEquals("The index Term should not be included.", 0, result.length);
652 result = is.search(qp.parse("[ \u0633 TO \u0638 ]"), null, 1000).scoreDocs;
653 assertEquals("The index Term should be included.", 1, result.length);
656 qp.setMultiTermRewriteMethod(MultiTermQuery.SCORING_BOOLEAN_QUERY_REWRITE);
657 result = is.search(qp.parse("[ \u062F TO \u0698 ]"), null, 1000).scoreDocs;
658 assertEquals("The index Term should not be included.", 0, result.length);
660 result = is.search(qp.parse("[ \u0633 TO \u0638 ]"), null, 1000).scoreDocs;
661 assertEquals("The index Term should be included.", 1, result.length);
667 private String escapeDateString(String s) {
668 if (s.contains(" ")) {
669 return "\"" + s + "\"";
675 /** for testing legacy DateField support */
676 private String getLegacyDate(String s) throws Exception {
677 DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT);
678 return DateField.dateToString(df.parse(s));
681 /** for testing DateTools support */
682 private String getDate(String s, DateTools.Resolution resolution)
684 DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT);
685 return getDate(df.parse(s), resolution);
688 /** for testing DateTools support */
689 private String getDate(Date d, DateTools.Resolution resolution)
691 if (resolution == null) {
692 return DateField.dateToString(d);
694 return DateTools.dateToString(d, resolution);
698 private String getLocalizedDate(int year, int month, int day) {
699 DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT);
700 Calendar calendar = new GregorianCalendar();
702 calendar.set(year, month, day);
703 calendar.set(Calendar.HOUR_OF_DAY, 23);
704 calendar.set(Calendar.MINUTE, 59);
705 calendar.set(Calendar.SECOND, 59);
706 calendar.set(Calendar.MILLISECOND, 999);
707 return df.format(calendar.getTime());
710 /** for testing legacy DateField support */
711 public void testLegacyDateRange() throws Exception {
712 String startDate = getLocalizedDate(2002, 1, 1);
713 String endDate = getLocalizedDate(2002, 1, 4);
714 Calendar endDateExpected = new GregorianCalendar();
715 endDateExpected.clear();
716 endDateExpected.set(2002, 1, 4, 23, 59, 59);
717 endDateExpected.set(Calendar.MILLISECOND, 999);
718 assertQueryEquals("[ " + escapeDateString(startDate) + " TO " + escapeDateString(endDate) + "]", null, "["
719 + getLegacyDate(startDate) + " TO "
720 + DateField.dateToString(endDateExpected.getTime()) + "]");
721 assertQueryEquals("{ " + escapeDateString(startDate) + " " + escapeDateString(endDate) + " }", null, "{"
722 + getLegacyDate(startDate) + " TO " + getLegacyDate(endDate) + "}");
725 public void testDateRange() throws Exception {
726 String startDate = getLocalizedDate(2002, 1, 1);
727 String endDate = getLocalizedDate(2002, 1, 4);
728 Calendar endDateExpected = new GregorianCalendar();
729 endDateExpected.clear();
730 endDateExpected.set(2002, 1, 4, 23, 59, 59);
731 endDateExpected.set(Calendar.MILLISECOND, 999);
732 final String defaultField = "default";
733 final String monthField = "month";
734 final String hourField = "hour";
735 QueryParserWrapper qp = new QueryParserWrapper("field",
736 new SimpleAnalyzer(TEST_VERSION_CURRENT));
738 // Don't set any date resolution and verify if DateField is used
739 assertDateRangeQueryEquals(qp, defaultField, startDate, endDate,
740 endDateExpected.getTime(), null);
742 // set a field specific date resolution
743 qp.setDateResolution(monthField, DateTools.Resolution.MONTH);
745 // DateField should still be used for defaultField
746 assertDateRangeQueryEquals(qp, defaultField, startDate, endDate,
747 endDateExpected.getTime(), null);
749 // set default date resolution to MILLISECOND
750 qp.setDateResolution(DateTools.Resolution.MILLISECOND);
752 // set second field specific date resolution
753 qp.setDateResolution(hourField, DateTools.Resolution.HOUR);
755 // for this field no field specific date resolution has been set,
756 // so verify if the default resolution is used
757 assertDateRangeQueryEquals(qp, defaultField, startDate, endDate,
758 endDateExpected.getTime(), DateTools.Resolution.MILLISECOND);
760 // verify if field specific date resolutions are used for these two fields
761 assertDateRangeQueryEquals(qp, monthField, startDate, endDate,
762 endDateExpected.getTime(), DateTools.Resolution.MONTH);
764 assertDateRangeQueryEquals(qp, hourField, startDate, endDate,
765 endDateExpected.getTime(), DateTools.Resolution.HOUR);
768 public void assertDateRangeQueryEquals(QueryParserWrapper qp, String field,
769 String startDate, String endDate, Date endDateInclusive,
770 DateTools.Resolution resolution) throws Exception {
771 assertQueryEquals(qp, field, field + ":[" + escapeDateString(startDate) + " TO " + escapeDateString(endDate)
772 + "]", "[" + getDate(startDate, resolution) + " TO "
773 + getDate(endDateInclusive, resolution) + "]");
774 assertQueryEquals(qp, field, field + ":{" + escapeDateString(startDate) + " TO " + escapeDateString(endDate)
775 + "}", "{" + getDate(startDate, resolution) + " TO "
776 + getDate(endDate, resolution) + "}");
779 public void testEscaped() throws Exception {
780 Analyzer a = new WhitespaceAnalyzer(TEST_VERSION_CURRENT);
783 * assertQueryEquals("\\[brackets", a, "\\[brackets");
784 * assertQueryEquals("\\[brackets", null, "brackets");
785 * assertQueryEquals("\\\\", a, "\\\\"); assertQueryEquals("\\+blah", a,
786 * "\\+blah"); assertQueryEquals("\\(blah", a, "\\(blah");
788 * assertQueryEquals("\\-blah", a, "\\-blah"); assertQueryEquals("\\!blah",
789 * a, "\\!blah"); assertQueryEquals("\\{blah", a, "\\{blah");
790 * assertQueryEquals("\\}blah", a, "\\}blah"); assertQueryEquals("\\:blah",
791 * a, "\\:blah"); assertQueryEquals("\\^blah", a, "\\^blah");
792 * assertQueryEquals("\\[blah", a, "\\[blah"); assertQueryEquals("\\]blah",
793 * a, "\\]blah"); assertQueryEquals("\\\"blah", a, "\\\"blah");
794 * assertQueryEquals("\\(blah", a, "\\(blah"); assertQueryEquals("\\)blah",
795 * a, "\\)blah"); assertQueryEquals("\\~blah", a, "\\~blah");
796 * assertQueryEquals("\\*blah", a, "\\*blah"); assertQueryEquals("\\?blah",
797 * a, "\\?blah"); //assertQueryEquals("foo \\&\\& bar", a,
798 * "foo \\&\\& bar"); //assertQueryEquals("foo \\|| bar", a,
799 * "foo \\|| bar"); //assertQueryEquals("foo \\AND bar", a,
803 assertQueryEquals("\\a", a, "a");
805 assertQueryEquals("a\\-b:c", a, "a-b:c");
806 assertQueryEquals("a\\+b:c", a, "a+b:c");
807 assertQueryEquals("a\\:b:c", a, "a:b:c");
808 assertQueryEquals("a\\\\b:c", a, "a\\b:c");
810 assertQueryEquals("a:b\\-c", a, "a:b-c");
811 assertQueryEquals("a:b\\+c", a, "a:b+c");
812 assertQueryEquals("a:b\\:c", a, "a:b:c");
813 assertQueryEquals("a:b\\\\c", a, "a:b\\c");
815 assertQueryEquals("a:b\\-c*", a, "a:b-c*");
816 assertQueryEquals("a:b\\+c*", a, "a:b+c*");
817 assertQueryEquals("a:b\\:c*", a, "a:b:c*");
819 assertQueryEquals("a:b\\\\c*", a, "a:b\\c*");
821 assertQueryEquals("a:b\\-?c", a, "a:b-?c");
822 assertQueryEquals("a:b\\+?c", a, "a:b+?c");
823 assertQueryEquals("a:b\\:?c", a, "a:b:?c");
825 assertQueryEquals("a:b\\\\?c", a, "a:b\\?c");
827 assertQueryEquals("a:b\\-c~", a, "a:b-c~0.5");
828 assertQueryEquals("a:b\\+c~", a, "a:b+c~0.5");
829 assertQueryEquals("a:b\\:c~", a, "a:b:c~0.5");
830 assertQueryEquals("a:b\\\\c~", a, "a:b\\c~0.5");
832 // TODO: implement Range queries on QueryParser
833 assertQueryEquals("[ a\\- TO a\\+ ]", null, "[a- TO a+]");
834 assertQueryEquals("[ a\\: TO a\\~ ]", null, "[a: TO a~]");
835 assertQueryEquals("[ a\\\\ TO a\\* ]", null, "[a\\ TO a*]");
838 "[\"c\\:\\\\temp\\\\\\~foo0.txt\" TO \"c\\:\\\\temp\\\\\\~foo9.txt\"]",
839 a, "[c:\\temp\\~foo0.txt TO c:\\temp\\~foo9.txt]");
841 assertQueryEquals("a\\\\\\+b", a, "a\\+b");
843 assertQueryEquals("a \\\"b c\\\" d", a, "a \"b c\" d");
844 assertQueryEquals("\"a \\\"b c\\\" d\"", a, "\"a \"b c\" d\"");
845 assertQueryEquals("\"a \\+b c d\"", a, "\"a +b c d\"");
847 assertQueryEquals("c\\:\\\\temp\\\\\\~foo.txt", a, "c:\\temp\\~foo.txt");
849 assertParseException("XY\\"); // there must be a character after the escape
852 // test unicode escaping
853 assertQueryEquals("a\\u0062c", a, "abc");
854 assertQueryEquals("XY\\u005a", a, "XYZ");
855 assertQueryEquals("XY\\u005A", a, "XYZ");
856 assertQueryEquals("\"a \\\\\\u0028\\u0062\\\" c\"", a, "\"a \\(b\" c\"");
858 assertParseException("XY\\u005G"); // test non-hex character in escaped
860 assertParseException("XY\\u005"); // test incomplete escaped unicode
863 // Tests bug LUCENE-800
864 assertQueryEquals("(item:\\\\ item:ABCD\\\\)", a, "item:\\ item:ABCD\\");
865 assertParseException("(item:\\\\ item:ABCD\\\\))"); // unmatched closing
867 assertQueryEquals("\\*", a, "*");
868 assertQueryEquals("\\\\", a, "\\"); // escaped backslash
870 assertParseException("\\"); // a backslash must always be escaped
873 assertQueryEquals("(\"a\\\\\") or (\"b\")", a, "a\\ or b");
876 public void testQueryStringEscaping() throws Exception {
877 Analyzer a = new WhitespaceAnalyzer(TEST_VERSION_CURRENT);
879 assertEscapedQueryEquals("a-b:c", a, "a\\-b\\:c");
880 assertEscapedQueryEquals("a+b:c", a, "a\\+b\\:c");
881 assertEscapedQueryEquals("a:b:c", a, "a\\:b\\:c");
882 assertEscapedQueryEquals("a\\b:c", a, "a\\\\b\\:c");
884 assertEscapedQueryEquals("a:b-c", a, "a\\:b\\-c");
885 assertEscapedQueryEquals("a:b+c", a, "a\\:b\\+c");
886 assertEscapedQueryEquals("a:b:c", a, "a\\:b\\:c");
887 assertEscapedQueryEquals("a:b\\c", a, "a\\:b\\\\c");
889 assertEscapedQueryEquals("a:b-c*", a, "a\\:b\\-c\\*");
890 assertEscapedQueryEquals("a:b+c*", a, "a\\:b\\+c\\*");
891 assertEscapedQueryEquals("a:b:c*", a, "a\\:b\\:c\\*");
893 assertEscapedQueryEquals("a:b\\\\c*", a, "a\\:b\\\\\\\\c\\*");
895 assertEscapedQueryEquals("a:b-?c", a, "a\\:b\\-\\?c");
896 assertEscapedQueryEquals("a:b+?c", a, "a\\:b\\+\\?c");
897 assertEscapedQueryEquals("a:b:?c", a, "a\\:b\\:\\?c");
899 assertEscapedQueryEquals("a:b?c", a, "a\\:b\\?c");
901 assertEscapedQueryEquals("a:b-c~", a, "a\\:b\\-c\\~");
902 assertEscapedQueryEquals("a:b+c~", a, "a\\:b\\+c\\~");
903 assertEscapedQueryEquals("a:b:c~", a, "a\\:b\\:c\\~");
904 assertEscapedQueryEquals("a:b\\c~", a, "a\\:b\\\\c\\~");
906 assertEscapedQueryEquals("[ a - TO a+ ]", null, "\\[ a \\- TO a\\+ \\]");
907 assertEscapedQueryEquals("[ a : TO a~ ]", null, "\\[ a \\: TO a\\~ \\]");
908 assertEscapedQueryEquals("[ a\\ TO a* ]", null, "\\[ a\\\\ TO a\\* \\]");
911 assertEscapedQueryEquals("|| abc ||", a, "\\|\\| abc \\|\\|");
912 assertEscapedQueryEquals("&& abc &&", a, "\\&\\& abc \\&\\&");
915 public void testTabNewlineCarriageReturn() throws Exception {
916 assertQueryEqualsDOA("+weltbank +worlbank", null, "+weltbank +worlbank");
918 assertQueryEqualsDOA("+weltbank\n+worlbank", null, "+weltbank +worlbank");
919 assertQueryEqualsDOA("weltbank \n+worlbank", null, "+weltbank +worlbank");
920 assertQueryEqualsDOA("weltbank \n +worlbank", null, "+weltbank +worlbank");
922 assertQueryEqualsDOA("+weltbank\r+worlbank", null, "+weltbank +worlbank");
923 assertQueryEqualsDOA("weltbank \r+worlbank", null, "+weltbank +worlbank");
924 assertQueryEqualsDOA("weltbank \r +worlbank", null, "+weltbank +worlbank");
926 assertQueryEqualsDOA("+weltbank\r\n+worlbank", null, "+weltbank +worlbank");
927 assertQueryEqualsDOA("weltbank \r\n+worlbank", null, "+weltbank +worlbank");
928 assertQueryEqualsDOA("weltbank \r\n +worlbank", null, "+weltbank +worlbank");
929 assertQueryEqualsDOA("weltbank \r \n +worlbank", null,
930 "+weltbank +worlbank");
932 assertQueryEqualsDOA("+weltbank\t+worlbank", null, "+weltbank +worlbank");
933 assertQueryEqualsDOA("weltbank \t+worlbank", null, "+weltbank +worlbank");
934 assertQueryEqualsDOA("weltbank \t +worlbank", null, "+weltbank +worlbank");
937 public void testSimpleDAO() throws Exception {
938 assertQueryEqualsDOA("term term term", null, "+term +term +term");
939 assertQueryEqualsDOA("term +term term", null, "+term +term +term");
940 assertQueryEqualsDOA("term term +term", null, "+term +term +term");
941 assertQueryEqualsDOA("term +term +term", null, "+term +term +term");
942 assertQueryEqualsDOA("-term term term", null, "-term +term +term");
945 public void testBoost() throws Exception {
946 StandardAnalyzer oneStopAnalyzer = new StandardAnalyzer(TEST_VERSION_CURRENT, Collections.singleton("on"));
947 QueryParserWrapper qp = new QueryParserWrapper("field", oneStopAnalyzer);
948 Query q = qp.parse("on^1.0");
950 q = qp.parse("\"hello\"^2.0");
952 assertEquals(q.getBoost(), (float) 2.0, (float) 0.5);
953 q = qp.parse("hello^2.0");
955 assertEquals(q.getBoost(), (float) 2.0, (float) 0.5);
956 q = qp.parse("\"on\"^1.0");
959 QueryParserWrapper qp2 = new QueryParserWrapper("field",
960 new StandardAnalyzer(TEST_VERSION_CURRENT));
961 q = qp2.parse("the^3");
962 // "the" is a stop word so the result is an empty query:
964 assertEquals("", q.toString());
965 assertEquals(1.0f, q.getBoost(), 0.01f);
968 public void assertParseException(String queryString) throws Exception {
970 getQuery(queryString, null);
971 } catch (ParseException expected) {
974 fail("ParseException expected, not thrown");
977 public void testException() throws Exception {
978 assertParseException("\"some phrase");
979 assertParseException("(foo bar");
980 assertParseException("foo bar))");
981 assertParseException("field:term:with:colon some more terms");
982 assertParseException("(sub query)^5.0^2.0 plus more");
983 assertParseException("secret AND illegal) AND access:confidential");
986 public void testCustomQueryParserWildcard() {
988 new QPTestParser("contents", new WhitespaceAnalyzer(TEST_VERSION_CURRENT)).parse("a?t");
989 fail("Wildcard queries should not be allowed");
990 } catch (ParseException expected) {
991 // expected exception
995 public void testCustomQueryParserFuzzy() throws Exception {
997 new QPTestParser("contents", new WhitespaceAnalyzer(TEST_VERSION_CURRENT)).parse("xunit~");
998 fail("Fuzzy queries should not be allowed");
999 } catch (ParseException expected) {
1000 // expected exception
1004 public void testBooleanQuery() throws Exception {
1005 BooleanQuery.setMaxClauseCount(2);
1007 QueryParserWrapper qp = new QueryParserWrapper("field",
1008 new WhitespaceAnalyzer(TEST_VERSION_CURRENT));
1009 qp.parse("one two three");
1010 fail("ParseException expected due to too many boolean clauses");
1011 } catch (ParseException expected) {
1012 // too many boolean clauses, so ParseException is expected
1017 * This test differs from TestPrecedenceQueryParser
1019 public void testPrecedence() throws Exception {
1020 QueryParserWrapper qp = new QueryParserWrapper("field",
1021 new WhitespaceAnalyzer(TEST_VERSION_CURRENT));
1022 Query query1 = qp.parse("A AND B OR C AND D");
1023 Query query2 = qp.parse("+A +B +C +D");
1025 assertEquals(query1, query2);
1028 public void testLocalDateFormat() throws IOException, ParseException {
1030 Directory ramDir = newDirectory();
1031 IndexWriter iw = new IndexWriter(ramDir, new WhitespaceAnalyzer(TEST_VERSION_CURRENT), true,
1032 IndexWriter.MaxFieldLength.LIMITED);
1033 addDateDoc("a", 2005, 12, 2, 10, 15, 33, iw);
1034 addDateDoc("b", 2005, 12, 4, 22, 15, 00, iw);
1036 IndexSearcher is = new IndexSearcher(ramDir, true);
1037 assertHits(1, "[12/1/2005 TO 12/3/2005]", is);
1038 assertHits(2, "[12/1/2005 TO 12/4/2005]", is);
1039 assertHits(1, "[12/3/2005 TO 12/4/2005]", is);
1040 assertHits(1, "{12/1/2005 TO 12/3/2005}", is);
1041 assertHits(1, "{12/1/2005 TO 12/4/2005}", is);
1042 assertHits(0, "{12/3/2005 TO 12/4/2005}", is);
1047 public void testStarParsing() throws Exception {
1048 // final int[] type = new int[1];
1049 // QueryParser qp = new QueryParserWrapper("field", new
1050 // WhitespaceAnalyzer()) {
1051 // protected Query getWildcardQuery(String field, String termStr) throws
1053 // // override error checking of superclass
1055 // return new TermQuery(new Term(field,termStr));
1057 // protected Query getPrefixQuery(String field, String termStr) throws
1059 // // override error checking of superclass
1061 // return new TermQuery(new Term(field,termStr));
1064 // protected Query getFieldQuery(String field, String queryText) throws
1067 // return super.getFieldQuery(field, queryText);
1073 // tq = (TermQuery)qp.parse("foo:zoo*");
1074 // assertEquals("zoo",tq.getTerm().text());
1075 // assertEquals(2,type[0]);
1077 // tq = (TermQuery)qp.parse("foo:zoo*^2");
1078 // assertEquals("zoo",tq.getTerm().text());
1079 // assertEquals(2,type[0]);
1080 // assertEquals(tq.getBoost(),2,0);
1082 // tq = (TermQuery)qp.parse("foo:*");
1083 // assertEquals("*",tq.getTerm().text());
1084 // assertEquals(1,type[0]); // could be a valid prefix query in the future
1087 // tq = (TermQuery)qp.parse("foo:*^2");
1088 // assertEquals("*",tq.getTerm().text());
1089 // assertEquals(1,type[0]);
1090 // assertEquals(tq.getBoost(),2,0);
1092 // tq = (TermQuery)qp.parse("*:foo");
1093 // assertEquals("*",tq.getTerm().field());
1094 // assertEquals("foo",tq.getTerm().text());
1095 // assertEquals(3,type[0]);
1097 // tq = (TermQuery)qp.parse("*:*");
1098 // assertEquals("*",tq.getTerm().field());
1099 // assertEquals("*",tq.getTerm().text());
1100 // assertEquals(1,type[0]); // could be handled as a prefix query in the
1103 // tq = (TermQuery)qp.parse("(*:*)");
1104 // assertEquals("*",tq.getTerm().field());
1105 // assertEquals("*",tq.getTerm().text());
1106 // assertEquals(1,type[0]);
1110 public void testStopwords() throws Exception {
1111 QueryParserWrapper qp = new QueryParserWrapper("a", new StopAnalyzer(TEST_VERSION_CURRENT, StopFilter.makeStopSet(TEST_VERSION_CURRENT, "the", "foo")));
1112 Query result = qp.parse("a:the OR a:foo");
1113 assertNotNull("result is null and it shouldn't be", result);
1114 assertTrue("result is not a BooleanQuery", result instanceof BooleanQuery);
1115 assertTrue(((BooleanQuery) result).clauses().size() + " does not equal: "
1116 + 0, ((BooleanQuery) result).clauses().size() == 0);
1117 result = qp.parse("a:woo OR a:the");
1118 assertNotNull("result is null and it shouldn't be", result);
1119 assertTrue("result is not a TermQuery", result instanceof TermQuery);
1121 .parse("(fieldX:xxxxx OR fieldy:xxxxxxxx)^2 AND (fieldx:the OR fieldy:foo)");
1122 assertNotNull("result is null and it shouldn't be", result);
1123 assertTrue("result is not a BooleanQuery", result instanceof BooleanQuery);
1124 if (VERBOSE) System.out.println("Result: " + result);
1125 assertTrue(((BooleanQuery) result).clauses().size() + " does not equal: "
1126 + 2, ((BooleanQuery) result).clauses().size() == 2);
1129 public void testPositionIncrement() throws Exception {
1130 QueryParserWrapper qp = new QueryParserWrapper("a", new StopAnalyzer(TEST_VERSION_CURRENT, StopFilter.makeStopSet(TEST_VERSION_CURRENT, "the", "in", "are", "this")));
1131 qp.setEnablePositionIncrements(true);
1132 String qtxt = "\"the words in poisitions pos02578 are stopped in this phrasequery\"";
1134 int expectedPositions[] = { 1, 3, 4, 6, 9 };
1135 PhraseQuery pq = (PhraseQuery) qp.parse(qtxt);
1136 // System.out.println("Query text: "+qtxt);
1137 // System.out.println("Result: "+pq);
1138 Term t[] = pq.getTerms();
1139 int pos[] = pq.getPositions();
1140 for (int i = 0; i < t.length; i++) {
1141 // System.out.println(i+". "+t[i]+" pos: "+pos[i]);
1142 assertEquals("term " + i + " = " + t[i] + " has wrong term-position!",
1143 expectedPositions[i], pos[i]);
1147 public void testMatchAllDocs() throws Exception {
1148 QueryParserWrapper qp = new QueryParserWrapper("field",
1149 new WhitespaceAnalyzer(TEST_VERSION_CURRENT));
1150 assertEquals(new MatchAllDocsQuery(), qp.parse("*:*"));
1151 assertEquals(new MatchAllDocsQuery(), qp.parse("(*:*)"));
1152 BooleanQuery bq = (BooleanQuery) qp.parse("+*:* -*:*");
1153 assertTrue(bq.getClauses()[0].getQuery() instanceof MatchAllDocsQuery);
1154 assertTrue(bq.getClauses()[1].getQuery() instanceof MatchAllDocsQuery);
1157 private void assertHits(int expected, String query, IndexSearcher is)
1158 throws ParseException, IOException {
1159 QueryParserWrapper qp = new QueryParserWrapper("date",
1160 new WhitespaceAnalyzer(TEST_VERSION_CURRENT));
1161 qp.setLocale(Locale.ENGLISH);
1162 Query q = qp.parse(query);
1163 ScoreDoc[] hits = is.search(q, null, 1000).scoreDocs;
1164 assertEquals(expected, hits.length);
1167 private void addDateDoc(String content, int year, int month, int day,
1168 int hour, int minute, int second, IndexWriter iw) throws IOException {
1169 Document d = new Document();
1170 d.add(newField("f", content, Field.Store.YES, Field.Index.ANALYZED));
1171 Calendar cal = Calendar.getInstance(Locale.ENGLISH);
1172 cal.set(year, month - 1, day, hour, minute, second);
1173 d.add(newField("date", DateField.dateToString(cal.getTime()),
1174 Field.Store.YES, Field.Index.NOT_ANALYZED));
1179 public void tearDown() throws Exception {
1180 BooleanQuery.setMaxClauseCount(originalMaxClauses);