@Test
  public void testAnyOnArrayLiteral() throws Exception {
    Reference ref = createReference("d", DataTypes.STRING);
    Literal stringArrayLiteral =
        Literal.newLiteral(
            new Object[] {new BytesRef("a"), new BytesRef("b"), new BytesRef("c")},
            new ArrayType(DataTypes.STRING));

    // col != ANY (1,2,3)
    Query neqQuery = convert(whereClause(AnyNeqOperator.NAME, ref, stringArrayLiteral));
    assertThat(neqQuery, instanceOf(FilteredQuery.class));
    assertThat(((FilteredQuery) neqQuery).getFilter(), instanceOf(BooleanFilter.class));
    BooleanFilter filter = (BooleanFilter) ((FilteredQuery) neqQuery).getFilter();
    assertThat(filter.toString(), is("BooleanFilter(-BooleanFilter(+d:a +d:b +d:c))"));

    // col like any (1,2,3)
    Query likeQuery = convert(whereClause(AnyLikeOperator.NAME, ref, stringArrayLiteral));
    assertThat(likeQuery, instanceOf(BooleanQuery.class));
    BooleanQuery likeBQuery = (BooleanQuery) likeQuery;
    assertThat(likeBQuery.clauses().size(), is(3));
    for (int i = 0; i < 2; i++) {
      // like --> XConstantScoreQuery with regexp-filter
      Query filteredQuery = likeBQuery.clauses().get(i).getQuery();
      assertThat(filteredQuery, instanceOf(XConstantScoreQuery.class));
      assertThat(((XConstantScoreQuery) filteredQuery).getFilter(), instanceOf(RegexpFilter.class));
    }

    // col not like any (1,2,3)
    Query notLikeQuery = convert(whereClause(AnyNotLikeOperator.NAME, ref, stringArrayLiteral));
    assertThat(notLikeQuery, instanceOf(BooleanQuery.class));
    BooleanQuery notLikeBQuery = (BooleanQuery) notLikeQuery;
    assertThat(notLikeBQuery.clauses(), hasSize(1));
    BooleanClause clause = notLikeBQuery.clauses().get(0);
    assertThat(clause.getOccur(), is(BooleanClause.Occur.MUST_NOT));
    assertThat(((BooleanQuery) clause.getQuery()).clauses(), hasSize(3));
    for (BooleanClause innerClause : ((BooleanQuery) clause.getQuery()).clauses()) {
      assertThat(innerClause.getOccur(), is(BooleanClause.Occur.MUST));
      assertThat(innerClause.getQuery(), instanceOf(XConstantScoreQuery.class));
      assertThat(
          ((XConstantScoreQuery) innerClause.getQuery()).getFilter(),
          instanceOf(RegexpFilter.class));
    }

    // col < any (1,2,3)
    Query ltQuery2 = convert(whereClause(AnyLtOperator.NAME, ref, stringArrayLiteral));
    assertThat(ltQuery2, instanceOf(BooleanQuery.class));
    BooleanQuery ltBQuery = (BooleanQuery) ltQuery2;
    assertThat(ltBQuery.toString(), is("(d:{* TO a} d:{* TO b} d:{* TO c})~1"));
  }
 @Override
 public boolean shouldCache(Query query, LeafReaderContext context) throws IOException {
   if (query instanceof MatchAllDocsQuery
       // MatchNoDocsQuery currently rewrites to a BooleanQuery,
       // but who knows, it might get its own Weight one day
       || query instanceof MatchNoDocsQuery) {
     return false;
   }
   if (query instanceof BooleanQuery) {
     BooleanQuery bq = (BooleanQuery) query;
     if (bq.clauses().isEmpty()) {
       return false;
     }
   }
   if (query instanceof DisjunctionMaxQuery) {
     DisjunctionMaxQuery dmq = (DisjunctionMaxQuery) query;
     if (dmq.getDisjuncts().isEmpty()) {
       return false;
     }
   }
   if (segmentPolicy.shouldCache(query, context) == false) {
     return false;
   }
   final int frequency = frequency(query);
   final int minFrequency = minFrequencyToCache(query);
   return frequency >= minFrequency;
 }
  public void testToQueryBooleanQueryMultipleBoosts() throws Exception {
    assumeTrue("test runs only when at least a type is registered", getCurrentTypes().length > 0);
    int numBoosts = randomIntBetween(2, 10);
    float[] boosts = new float[numBoosts + 1];
    String queryStringPrefix = "";
    String queryStringSuffix = "";
    for (int i = 0; i < boosts.length - 1; i++) {
      float boost = 2.0f / randomIntBetween(3, 20);
      boosts[i] = boost;
      queryStringPrefix += "(";
      queryStringSuffix += ")^" + boost;
    }
    String queryString = queryStringPrefix + "foo bar" + queryStringSuffix;

    float mainBoost = 2.0f / randomIntBetween(3, 20);
    boosts[boosts.length - 1] = mainBoost;
    QueryStringQueryBuilder queryStringQueryBuilder =
        new QueryStringQueryBuilder(queryString)
            .field(STRING_FIELD_NAME)
            .minimumShouldMatch("2")
            .boost(mainBoost);
    Query query = queryStringQueryBuilder.toQuery(createShardContext());

    for (int i = boosts.length - 1; i >= 0; i--) {
      assertThat(query, instanceOf(BoostQuery.class));
      BoostQuery boostQuery = (BoostQuery) query;
      assertThat(boostQuery.getBoost(), equalTo(boosts[i]));
      query = boostQuery.getQuery();
    }

    assertThat(query, instanceOf(BooleanQuery.class));
    BooleanQuery booleanQuery = (BooleanQuery) query;
    assertThat(booleanQuery.getMinimumNumberShouldMatch(), equalTo(2));
    assertThat(booleanQuery.clauses().get(0).getOccur(), equalTo(BooleanClause.Occur.SHOULD));
    assertThat(
        booleanQuery.clauses().get(0).getQuery(),
        equalTo(new TermQuery(new Term(STRING_FIELD_NAME, "foo"))));
    assertThat(booleanQuery.clauses().get(1).getOccur(), equalTo(BooleanClause.Occur.SHOULD));
    assertThat(
        booleanQuery.clauses().get(1).getQuery(),
        equalTo(new TermQuery(new Term(STRING_FIELD_NAME, "bar"))));
  }
 public void testToQueryFieldsWildcard() throws Exception {
   assumeTrue("test runs only when at least a type is registered", getCurrentTypes().length > 0);
   Query query =
       queryStringQuery("test")
           .field("mapped_str*")
           .useDisMax(false)
           .toQuery(createShardContext());
   assertThat(query, instanceOf(BooleanQuery.class));
   BooleanQuery bQuery = (BooleanQuery) query;
   assertThat(bQuery.clauses().size(), equalTo(2));
   assertThat(
       assertBooleanSubQuery(query, TermQuery.class, 0).getTerm(),
       equalTo(new Term(STRING_FIELD_NAME, "test")));
   assertThat(
       assertBooleanSubQuery(query, TermQuery.class, 1).getTerm(),
       equalTo(new Term(STRING_FIELD_NAME_2, "test")));
 }
 static void assertLateParsingQuery(Query query, String type, String id) throws IOException {
   assertThat(query, instanceOf(HasChildQueryBuilder.LateParsingQuery.class));
   HasChildQueryBuilder.LateParsingQuery lateParsingQuery =
       (HasChildQueryBuilder.LateParsingQuery) query;
   assertThat(lateParsingQuery.getInnerQuery(), instanceOf(BooleanQuery.class));
   BooleanQuery booleanQuery = (BooleanQuery) lateParsingQuery.getInnerQuery();
   assertThat(booleanQuery.clauses().size(), equalTo(2));
   // check the inner ids query, we have to call rewrite to get to check the type it's executed
   // against
   assertThat(booleanQuery.clauses().get(0).getOccur(), equalTo(BooleanClause.Occur.MUST));
   assertThat(booleanQuery.clauses().get(0).getQuery(), instanceOf(TermsQuery.class));
   TermsQuery termsQuery = (TermsQuery) booleanQuery.clauses().get(0).getQuery();
   Query rewrittenTermsQuery = termsQuery.rewrite(null);
   assertThat(rewrittenTermsQuery, instanceOf(ConstantScoreQuery.class));
   ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) rewrittenTermsQuery;
   assertThat(constantScoreQuery.getQuery(), instanceOf(BooleanQuery.class));
   BooleanQuery booleanTermsQuery = (BooleanQuery) constantScoreQuery.getQuery();
   assertThat(booleanTermsQuery.clauses().size(), equalTo(1));
   assertThat(booleanTermsQuery.clauses().get(0).getOccur(), equalTo(BooleanClause.Occur.SHOULD));
   assertThat(booleanTermsQuery.clauses().get(0).getQuery(), instanceOf(TermQuery.class));
   TermQuery termQuery = (TermQuery) booleanTermsQuery.clauses().get(0).getQuery();
   assertThat(termQuery.getTerm().field(), equalTo(UidFieldMapper.NAME));
   // we want to make sure that the inner ids query gets executed against the child type rather
   // than the main type we initially set to the context
   BytesRef[] ids =
       Uid.createUidsForTypesAndIds(
           Collections.singletonList(type), Collections.singletonList(id));
   assertThat(termQuery.getTerm().bytes(), equalTo(ids[0]));
   // check the type filter
   assertThat(booleanQuery.clauses().get(1).getOccur(), equalTo(BooleanClause.Occur.FILTER));
   assertThat(booleanQuery.clauses().get(1).getQuery(), instanceOf(ConstantScoreQuery.class));
   ConstantScoreQuery typeConstantScoreQuery =
       (ConstantScoreQuery) booleanQuery.clauses().get(1).getQuery();
   assertThat(typeConstantScoreQuery.getQuery(), instanceOf(TermQuery.class));
   TermQuery typeTermQuery = (TermQuery) typeConstantScoreQuery.getQuery();
   assertThat(typeTermQuery.getTerm().field(), equalTo(TypeFieldMapper.NAME));
   assertThat(typeTermQuery.getTerm().text(), equalTo(type));
 }