Index: QueryParser.jj =================================================================== RCS file: /home/cvspublic/jakarta-lucene/src/java/org/apache/lucene/queryParser/QueryParser.jj,v retrieving revision 1.39 diff -u -r1.39 QueryParser.jj --- QueryParser.jj 26 Jan 2004 18:53:14 -0000 1.39 +++ QueryParser.jj 10 Feb 2004 20:32:30 -0000 @@ -362,6 +362,11 @@ */ protected Query getBooleanQuery(Vector clauses) throws ParseException { + // Clauses size 0 could happen when terms have been + // eliminated because they were stopwords + // best we can do is to return null I guess + if (clauses.size()==0) return null; + BooleanQuery query = new BooleanQuery(); for (int i = 0; i < clauses.size(); i++) { query.add((BooleanClause)clauses.elementAt(i)); @@ -447,6 +452,22 @@ Term t = new Term(field, termStr); return new FuzzyQuery(t); } + + /** + * Returns a String where the escape char has been + * removed or kept once if there was a double escape + */ + private String discardEscapeChar(String input) { + char[] caSource=input.toCharArray(); + char[] caDest=new char[caSource.length]; + int j=0; + for (int i=0;i0 && caSource[i-1]=='\\')) + caDest[j++]=caSource[i]; + } + return new String(caDest,0,j); + } public static void main(String[] args) throws Exception { QueryParser qp = new QueryParser("field", @@ -584,7 +605,9 @@ { [ LOOKAHEAD(2) - fieldToken= { field = fieldToken.image; } + fieldToken= { + field=discardEscapeChar(fieldToken.image); + } ] ( @@ -624,15 +647,17 @@ [ { fuzzy=true; } ] [ boost= [ { fuzzy=true; } ] ] { + String termImage=discardEscapeChar(term.image); if (wildcard) { - q = getWildcardQuery(field, term.image); + q = getWildcardQuery(field, termImage); } else if (prefix) { - q = getPrefixQuery(field, term.image.substring - (0, term.image.length()-1)); + q = getPrefixQuery(field, + discardEscapeChar(term.image.substring + (0, term.image.length()-1))); } else if (fuzzy) { - q = getFuzzyQuery(field, term.image); + q = getFuzzyQuery(field, termImage); } else { - q = getFieldQuery(field, analyzer, term.image); + q = getFieldQuery(field, analyzer, termImage); } } | ( ( goop1=|goop1= ) @@ -640,11 +665,16 @@ ) [ boost= ] { - if (goop1.kind == RANGEIN_QUOTED) + if (goop1.kind == RANGEIN_QUOTED) { goop1.image = goop1.image.substring(1, goop1.image.length()-1); - if (goop2.kind == RANGEIN_QUOTED) + } else { + goop1.image = discardEscapeChar(goop1.image); + } + if (goop2.kind == RANGEIN_QUOTED) { goop2.image = goop2.image.substring(1, goop2.image.length()-1); - + } else { + goop2.image = discardEscapeChar(goop2.image); + } q = getRangeQuery(field, analyzer, goop1.image, goop2.image, true); } | ( ( goop1=|goop1= ) @@ -652,11 +682,17 @@ ) [ boost= ] { - if (goop1.kind == RANGEEX_QUOTED) + if (goop1.kind == RANGEEX_QUOTED) { goop1.image = goop1.image.substring(1, goop1.image.length()-1); - if (goop2.kind == RANGEEX_QUOTED) + } else { + goop1.image = discardEscapeChar(goop1.image); + } + if (goop2.kind == RANGEEX_QUOTED) { goop2.image = goop2.image.substring(1, goop2.image.length()-1); - + } else { + goop2.image = discardEscapeChar(goop2.image); + } + q = getRangeQuery(field, analyzer, goop1.image, goop2.image, false); } | term= Index: TestQueryParser.java =================================================================== RCS file: /home/cvspublic/jakarta-lucene/src/test/org/apache/lucene/queryParser/TestQueryParser.java,v retrieving revision 1.23 diff -u -r1.23 TestQueryParser.java --- TestQueryParser.java 26 Nov 2003 11:03:30 -0000 1.23 +++ TestQueryParser.java 10 Feb 2004 20:32:55 -0000 @@ -157,6 +157,7 @@ public void assertQueryEquals(String query, Analyzer a, String result) throws Exception { Query q = getQuery(query, a); + if (result==null && q==null) return; String s = q.toString("field"); if (!s.equals(result)) { fail("Query /" + query + "/ yielded /" + s @@ -260,7 +261,8 @@ public void testNumber() throws Exception { // The numbers go away because SimpleAnalzyer ignores them - assertQueryEquals("3", null, ""); + //OK but what should be the result of such a query then? + assertQueryEquals("3", null, null); assertQueryEquals("term 1.0 1 2", null, "term"); assertQueryEquals("term term1 term2", null, "term term term"); @@ -314,7 +316,8 @@ "term \"phrase1 phrase2\" term"); assertQueryEquals("term AND NOT phrase term", qpAnalyzer, "+term -\"phrase1 phrase2\" term"); - assertQueryEquals("stop", qpAnalyzer, ""); + //once again, what should be the result of this query? + assertQueryEquals("stop", qpAnalyzer, null); assertTrue(getQuery("term term term", qpAnalyzer) instanceof BooleanQuery); assertTrue(getQuery("term +stop", qpAnalyzer) instanceof TermQuery); } @@ -355,7 +358,7 @@ public void testEscaped() throws Exception { Analyzer a = new WhitespaceAnalyzer(); - assertQueryEquals("\\[brackets", a, "\\[brackets"); + /* assertQueryEquals("\\[brackets", a, "\\[brackets"); assertQueryEquals("\\[brackets", null, "brackets"); assertQueryEquals("\\\\", a, "\\\\"); assertQueryEquals("\\+blah", a, "\\+blah"); @@ -377,8 +380,36 @@ assertQueryEquals("\\?blah", a, "\\?blah"); assertQueryEquals("foo \\&& bar", a, "foo \\&& bar"); assertQueryEquals("foo \\|| bar", a, "foo \\|| bar"); - assertQueryEquals("foo \\AND bar", a, "foo \\AND bar"); + assertQueryEquals("foo \\AND bar", a, "foo \\AND bar"); */ + assertQueryEquals("a\\-b:c",a,"a-b:c"); + assertQueryEquals("a\\+b:c",a,"a+b:c"); + assertQueryEquals("a\\:b:c",a,"a:b:c"); + assertQueryEquals("a\\\\b:c",a,"a\\b:c"); + + assertQueryEquals("a:b\\-c",a,"a:b-c"); + assertQueryEquals("a:b\\+c",a,"a:b+c"); + assertQueryEquals("a:b\\:c",a,"a:b:c"); + assertQueryEquals("a:b\\\\c",a,"a:b\\c"); + + assertQueryEquals("a:b\\-c*",a,"a:b-c*"); + assertQueryEquals("a:b\\+c*",a,"a:b+c*"); + assertQueryEquals("a:b\\:c*",a,"a:b:c*"); + assertQueryEquals("a:b\\\\c*",a,"a:b\\c*"); + + assertQueryEquals("a:b\\-?c",a,"a:b-?c"); + assertQueryEquals("a:b\\+?c",a,"a:b+?c"); + assertQueryEquals("a:b\\:?c",a,"a:b:?c"); + assertQueryEquals("a:b\\\\?c",a,"a:b\\?c"); + + assertQueryEquals("a:b\\-c~",a,"a:b-c~"); + assertQueryEquals("a:b\\+c~",a,"a:b+c~"); + assertQueryEquals("a:b\\:c~",a,"a:b:c~"); + assertQueryEquals("a:b\\\\c~",a,"a:b\\c~"); + + assertQueryEquals("[ a\\- TO a\\+ ]", null, "[a- TO a+]"); + assertQueryEquals("[ a\\: TO a\\~ ]", null, "[a: TO a~]"); + assertQueryEquals("[ a\\\\ TO a\\* ]", null, "[a\\ TO a*]"); } public void testSimpleDAO() @@ -395,18 +426,22 @@ StandardAnalyzer oneStopAnalyzer = new StandardAnalyzer(new String[]{"on"}); QueryParser qp = new QueryParser("field", oneStopAnalyzer); Query q = qp.parse("on^1.0"); - assertNotNull(q); + //on disappears, sentence doesn't respect the grammar anymore, what should be the result?? + assertNull(q); q = qp.parse("\"hello\"^2.0"); assertNotNull(q); assertEquals(q.getBoost(), (float) 2.0, (float) 0.5); q = qp.parse("hello^2.0"); assertNotNull(q); assertEquals(q.getBoost(), (float) 2.0, (float) 0.5); + //looks like analyzers look inside parenthesis and therefore + //on disappears here too and query is invalid q = qp.parse("\"on\"^1.0"); - assertNotNull(q); + assertNull(q); + //The disappears by standardanalyzer and query is invalid q = QueryParser.parse("the^3", "field", new StandardAnalyzer()); - assertNotNull(q); + assertNull(q); } public void testException() throws Exception { @@ -438,11 +473,17 @@ public void testBooleanQuery() throws Exception { BooleanQuery.setMaxClauseCount(2); try { - QueryParser.parse("one two three", "field", new WhitespaceAnalyzer()); + QueryParser.parse("one two three", "field", new WhitespaceAnalyzer()); fail("ParseException expected due to too many boolean clauses"); } catch (ParseException expected) { // too many boolean clauses, so ParseException is expected } + } + + public void testBug7574() throws Exception { + assertQueryEquals("(a:b || c:d) && (e:stop || f:stop)", qpAnalyzer, "a:b c:d"); + //TODO: why are the parenthesis still around nonstop? (still considered a clause probably) + assertQueryEquals("(a:b || c:d) && (e:stop || f:nonstop)", qpAnalyzer, "+(a:b c:d) +(f:nonstop)"); } public void tearDown() {