content: package org.apache.lucene.queryparser.flexible.aqp;
  
  import org.apache.lucene.analysis.core.WhitespaceAnalyzer;
  import org.apache.lucene.queryparser.flexible.core.QueryNodeException;
  import org.apache.lucene.queryparser.flexible.standard.StandardQueryParser;
  import org.apache.lucene.queryparser.flexible.standard.config.StandardQueryConfigHandler.Operator;
  import org.apache.lucene.search.BooleanQuery;
  import org.apache.lucene.search.Query;
  
  /**
   * This test case is a copy of the core Lucene query parser test, it was adapted
   * to use new QueryParserHelper instead of the old query parser.
   * <p>
   * Tests QueryParser.
   */
  public class TestAqpSLGSimple extends AqpTestAbstractCase {
  
      private final boolean verbose = true;
  
      private int originalMaxClauses;
  
      @Override
      public void setUp() throws Exception {
          super.setUp();
          originalMaxClauses = BooleanQuery.getMaxClauseCount();
          setGrammarName("StandardLuceneGrammar");
      }
  
      public void testBooleanQuery() throws Exception {
  
          WhitespaceAnalyzer analyzer = new WhitespaceAnalyzer();
  
          AqpQueryParser qp = getParser(analyzer);
  
          StandardQueryParser sp = (StandardQueryParser) getParser(analyzer, true);
  
          // DEFAULT OPERATOR IS AND
          qp.setDefaultOperator(Operator.AND);
          sp.setDefaultOperator(Operator.AND);
  
          // test the clause rewriting/optimization
          Query q = qp.parse("a -(-(+(-(x)^0.6))^0.2)^0.3", "");
          assertQueryMatch(qp, "a -(-(+(-(x)^0.6))^0.2)^0.3", "", "+a -(x)^0.3");
          assertQueryMatch(qp, "-(-(+(-(x)^0.6))^0.2)^0.3", "", "(x)^0.3"); // not
          // minus,
          // because
          // that is
          // not
          // allowed
          assertQueryMatch(qp, "-(-(+(-(x)^0.6))^0.2)^", "", "(x)^1.0"); // because defualt
          // boost is 1.0f
          assertQueryMatch(qp, "-(-(+(-(x)^))^0.2)^0.1", "", "(x)^0.1"); // because
          // defualt
          // boost is
          // 1.0f
  
          Query qa = sp.parse("kahnn-strauss", "x");
          Query qb = qp.parse("kahnn-strauss", "x");
          assertQueryMatch(qp, "kahnn-strauss", "x", qa.toString());
  
          qa = sp.parse("a \\\"b \\\"c d", "x");
          qb = qp.parse("a \\\"b \\\"c d", "x");
          assertQueryMatch(qp, "a \\\"b \\\"c d", "x", qa.toString());
  
          qa = sp.parse("\"a \\\"b c\\\" d\"", "x");
          qb = qp.parse("\"a \\\"b c\\\" d\"", "x");
          assertQueryMatch(qp, "\"a \\\"b c\\\" d\"", "x", qa.toString());
  
          assertQueryMatch(qp, "+(-(-(-(x)^0.6))^0.2)^", "field", "(field:x)^1.0");
          assertQueryMatch(qp, "+(-(-(-(x)^0.6))^0.2)^0.5", "field", "(field:x)^0.5");
  
          // the first element will be positive, because the negative X NOT Y
          // is currently implemented that way (the first must return something)
          // TODO: this should be:
          // "((+field:a +field:b)^0.8) -((+field:x +field:y)^0.2)"
  
          assertQueryMatch(qp, "(+(-(a b)))^0.8 OR -(x y)^0.2", "field",
                  "+(+field:a +field:b)^0.8 -(+field:x +field:y)^0.2");
  
          assertQueryMatch(qp, "(+(-(a b)))^0.8 AND -(x y)^0.2", "field",
                  "+(+field:a +field:b)^0.8 -(+field:x +field:y)^0.2");
  
          assertQueryMatch(qp, "(+(-(a b)))^0.8 -(x y)", "field",
                  "+(+field:a +field:b)^0.8 -(+field:x +field:y)");
          // or does -(x y) have different semantics? ... -field:x -field:y
          // +((-(+field:a +field:b))^0.8) -field:x -field:y
  
          assertQueryMatch(qp, "+((+(-(a b)))^0.8)^0.7 OR -(x y)^0.2", "field",
                  "+(+field:a +field:b)^0.7 -(+field:x +field:y)^0.2");
  
          assertQueryMatch(qp, "+title:(dog cat)", "field", "+title:dog +title:cat");
  
          assertQueryMatch(qp, "title:(+dog -cat)", "field", "+title:dog -title:cat");
          qp.setAllowLeadingWildcard(true);
          assertQueryMatch(qp, "\\*", "field", "field:*");
          qp.setAllowLeadingWildcard(false);
          assertQueryMatch(qp, "term~", "field", "field:term~2");
          assertQueryMatch(qp, "term~1", "field", "field:term~1");
          assertQueryMatch(qp, "term~2", "field", "field:term~2");
  
          assertQueryMatch(qp, "something", "field", "field:something");
  
          assertQueryMatch(qp, "x:something", "field", "x:something");
  
          assertQueryMatch(qp, "x:\"something else\"", "field",
                  "x:\"something else\"");
  
          assertQueryMatch(qp, "x:\"someth*\"", "field", "x:someth*");
  
          assertQueryMatch(qp, "x:\"someth?ng\"", "field", "x:someth?ng");
  
          assertQueryMatch(qp, "A AND B C AND D", "field",
                  "+field:A +field:B +field:C +field:D");
  
          assertQueryMatch(qp, "A AND B C AND D OR E", "field",
                  "+(+field:A +field:B) +((+field:C +field:D) field:E)");
  
          assertQueryMatch(qp, "one OR +two", "f", "f:one +f:two");
  
          assertQueryMatch(qp, "one OR two NOT three", "field",
                  "field:one (+field:two -field:three)");
  
          assertQueryMatch(qp, "one OR (two AND three) NOT four", "field",
                  "field:one (+(+field:two +field:three) -field:four)");
  
          assertQueryMatch(qp, "-one -two", "field", "-field:one -field:two");
  
          assertQueryMatch(qp, "x:one NOT y:two -three^0.5", "field",
                  "+(+x:one -y:two) -(field:three)^0.5");
  
          assertQueryMatch(qp, "one NOT two -three~0.2", "field",
                  "+(+field:one -field:two) -field:three~2");
  
          assertQueryMatch(qp, "one NOT two NOT three~0.2", "field",
                  "+field:one -field:two -field:three~2");
  
          assertQueryMatch(qp, "one two^0.5 three~0.2", "field",
                  "+field:one +(field:two)^0.5 +field:three~2");
  
          q = qp.parse("one (two three)^0.8", "field");
  
          // I know where the problem is: builder does not have access
          // to the config, so that when a default operator is changed
          // *after* the parser was instantiated, the builder behaves
          // the old way(s) -- this is a bigger problem, and I didn't
          // want to change the flex parser API
  
          // patch is in LUCENE-5014, I'll uncomment it here just to
          // not have to change the BooleanQueryNodeBuilder class
  
          //((QueryTreeBuilder) qp.getQueryBuilder()).setBuilder(BooleanQueryNode.class, new BooleanQueryNodeBuilder(BooleanClause.Occur.MUST));
  
          //qa = qp.parse("one (two three)^0.8", "field");
          //assertQueryMatch(qp, "one (two three)^0.8", "field",
          //    "+field:one +((+field:two +field:three)^0.8)");
  
          //assertQueryMatch(qp, "one (x:two three)^0.8", "field",
          //    "+field:one +((+x:two +field:three)^0.8)");
  
          // TODO: the original value was -((+one:two +one:three)^0.8)
          // but that is not a valid Lucene query (or is it?)
          assertQueryMatch(qp, "-one:(two three)^0.8", "field",
                  "(+one:two +one:three)^0.8");
  
  
          assertQueryMatch(qp, "one:(two three)^0.8", "field",
                  "(+one:two +one:three)^0.8");
  
          assertQueryMatch(qp, "+one:(two three)^0.8", "field",
                  "(+one:two +one:three)^0.8");
  
          assertQueryMatch(qp, "[one TO five]", "field", "field:[one TO five]");
  
          assertQueryMatch(qp, "z:[one TO five]", "field", "z:[one TO five]");
  
          assertQueryMatch(qp, "{one TO five}", "field", "field:{one TO five}");
  
          assertQueryMatch(qp, "z:{one TO five}", "field", "z:{one TO five}");
  
          assertQueryMatch(qp, "z:{\"one\" TO \"five\"}", "field", "z:{one TO five}");
  
          assertQueryMatch(qp, "z:{one TO *}", "field", "z:{one TO *}");
  
          assertQueryMatch(qp, "this +(that)", "field", "+field:this +field:that");
  
          assertQueryMatch(qp, "(this) (that)", "field", "+field:this +field:that");
  
          assertQueryMatch(qp, "this ((((+(that))))) ", "field",
                  "+field:this +field:that");
  
          assertQueryMatch(qp, "this (+(that)^0.7)", "field",
                  "+field:this +(field:that)^0.7");
  
          assertQueryMatch(qp, "this (+(that thus)^0.7)", "field",
                  "+field:this +(+field:that +field:thus)^0.7");
  
          assertQueryMatch(qp, "this (-(+(that thus))^0.7)", "field",
                  "+field:this -(+field:that +field:thus)^0.7");
  
          assertQueryMatch(qp, "this (+(-(+(-(that thus))^0.1))^0.3)", "field",
                  "+field:this +(+field:that +field:thus)^0.3");
  
          BooleanQuery.setMaxClauseCount(2);
          try {
              qp = getParser(new WhitespaceAnalyzer());
  
              qp.parse("one two three", "field");
              fail("ParseException expected due to too many boolean clauses");
          } catch (QueryNodeException expected) {
              // too many boolean clauses, so ParseException is expected
          }
  
  
          assertQueryMatch(qp, "*:*", "field", "*:*");
          qp.setAllowLeadingWildcard(true);
          assertQueryMatch(qp, "*", "field", "field:*");
          assertQueryMatch(qp, "field:*", "field", "field:*");
  
  
      }
  }
  