public void testDateRangeBoundaries() throws IOException {
    assumeTrue("test runs only when at least a type is registered", getCurrentTypes().length > 0);
    String query =
        "{\n"
            + "    \"range\" : {\n"
            + "        \""
            + DATE_FIELD_NAME
            + "\" : {\n"
            + "            \"gte\": \"2014-11-05||/M\",\n"
            + "            \"lte\": \"2014-12-08||/d\"\n"
            + "        }\n"
            + "    }\n"
            + "}\n";
    Query parsedQuery = parseQuery(query).toQuery(createShardContext()).rewrite(null);
    assertThat(parsedQuery, instanceOf(NumericRangeQuery.class));
    NumericRangeQuery rangeQuery = (NumericRangeQuery) parsedQuery;

    DateTime min = DateTime.parse("2014-11-01T00:00:00.000+00");
    assertThat(rangeQuery.getMin().longValue(), is(min.getMillis()));
    assertTrue(rangeQuery.includesMin());

    DateTime max = DateTime.parse("2014-12-08T23:59:59.999+00");
    assertThat(rangeQuery.getMax().longValue(), is(max.getMillis()));
    assertTrue(rangeQuery.includesMax());

    query =
        "{\n"
            + "    \"range\" : {\n"
            + "        \""
            + DATE_FIELD_NAME
            + "\" : {\n"
            + "            \"gt\": \"2014-11-05||/M\",\n"
            + "            \"lt\": \"2014-12-08||/d\"\n"
            + "        }\n"
            + "    }\n"
            + "}";
    parsedQuery = parseQuery(query).toQuery(createShardContext()).rewrite(null);
    assertThat(parsedQuery, instanceOf(NumericRangeQuery.class));
    rangeQuery = (NumericRangeQuery) parsedQuery;

    min = DateTime.parse("2014-11-30T23:59:59.999+00");
    assertThat(rangeQuery.getMin().longValue(), is(min.getMillis()));
    assertFalse(rangeQuery.includesMin());

    max = DateTime.parse("2014-12-08T00:00:00.000+00");
    assertThat(rangeQuery.getMax().longValue(), is(max.getMillis()));
    assertFalse(rangeQuery.includesMax());
  }
 @Override
 protected void doAssertLuceneQuery(
     RangeQueryBuilder queryBuilder, Query query, QueryShardContext context) throws IOException {
   if (getCurrentTypes().length == 0
       || (queryBuilder.fieldName().equals(DATE_FIELD_NAME) == false
           && queryBuilder.fieldName().equals(INT_FIELD_NAME) == false)) {
     assertThat(query, instanceOf(TermRangeQuery.class));
     TermRangeQuery termRangeQuery = (TermRangeQuery) query;
     assertThat(termRangeQuery.getField(), equalTo(queryBuilder.fieldName()));
     assertThat(termRangeQuery.getLowerTerm(), equalTo(BytesRefs.toBytesRef(queryBuilder.from())));
     assertThat(termRangeQuery.getUpperTerm(), equalTo(BytesRefs.toBytesRef(queryBuilder.to())));
     assertThat(termRangeQuery.includesLower(), equalTo(queryBuilder.includeLower()));
     assertThat(termRangeQuery.includesUpper(), equalTo(queryBuilder.includeUpper()));
   } else if (queryBuilder.fieldName().equals(DATE_FIELD_NAME)) {
     // we can't properly test unmapped dates because LateParsingQuery is package private
   } else if (queryBuilder.fieldName().equals(INT_FIELD_NAME)) {
     assertThat(query, instanceOf(NumericRangeQuery.class));
     NumericRangeQuery numericRangeQuery = (NumericRangeQuery) query;
     assertThat(numericRangeQuery.getField(), equalTo(queryBuilder.fieldName()));
     assertThat(numericRangeQuery.getMin(), equalTo(queryBuilder.from()));
     assertThat(numericRangeQuery.getMax(), equalTo(queryBuilder.to()));
     assertThat(numericRangeQuery.includesMin(), equalTo(queryBuilder.includeLower()));
     assertThat(numericRangeQuery.includesMax(), equalTo(queryBuilder.includeUpper()));
   } else {
     throw new UnsupportedOperationException();
   }
 }
  private static JsonObject convertNumericRangeQuery(NumericRangeQuery<?> query) {
    JsonObject interval = new JsonObject();
    if (query.getMin() != null) {
      interval.addProperty(query.includesMin() ? "gte" : "gt", query.getMin());
    }
    if (query.getMax() != null) {
      interval.addProperty(query.includesMax() ? "lte" : "lt", query.getMax());
    }
    interval.addProperty("boost", query.getBoost());

    JsonObject range =
        JsonBuilder.object()
            .add("range", JsonBuilder.object().add(query.getField(), interval))
            .build();

    return wrapQueryForNestedIfRequired(query.getField(), range);
  }
 public void testToQueryNumericField() throws IOException {
   assumeTrue("test runs only when at least a type is registered", getCurrentTypes().length > 0);
   Query parsedQuery =
       rangeQuery(INT_FIELD_NAME)
           .from(23)
           .to(54)
           .includeLower(true)
           .includeUpper(false)
           .toQuery(createShardContext());
   // since age is automatically registered in data, we encode it as numeric
   assertThat(parsedQuery, instanceOf(NumericRangeQuery.class));
   NumericRangeQuery rangeQuery = (NumericRangeQuery) parsedQuery;
   assertThat(rangeQuery.getField(), equalTo(INT_FIELD_NAME));
   assertThat(rangeQuery.getMin().intValue(), equalTo(23));
   assertThat(rangeQuery.getMax().intValue(), equalTo(54));
   assertThat(rangeQuery.includesMin(), equalTo(true));
   assertThat(rangeQuery.includesMax(), equalTo(false));
 }
  /** @see #toString(Query,IndexSchema) */
  public static void toString(Query query, IndexSchema schema, Appendable out, int flags)
      throws IOException {
    boolean writeBoost = true;

    if (query instanceof TermQuery) {
      TermQuery q = (TermQuery) query;
      Term t = q.getTerm();
      FieldType ft = writeFieldName(t.field(), schema, out, flags);
      writeFieldVal(t.bytes(), ft, out, flags);
    } else if (query instanceof TermRangeQuery) {
      TermRangeQuery q = (TermRangeQuery) query;
      String fname = q.getField();
      FieldType ft = writeFieldName(fname, schema, out, flags);
      out.append(q.includesLower() ? '[' : '{');
      BytesRef lt = q.getLowerTerm();
      BytesRef ut = q.getUpperTerm();
      if (lt == null) {
        out.append('*');
      } else {
        writeFieldVal(lt, ft, out, flags);
      }

      out.append(" TO ");

      if (ut == null) {
        out.append('*');
      } else {
        writeFieldVal(ut, ft, out, flags);
      }

      out.append(q.includesUpper() ? ']' : '}');
    } else if (query instanceof NumericRangeQuery) {
      NumericRangeQuery q = (NumericRangeQuery) query;
      String fname = q.getField();
      FieldType ft = writeFieldName(fname, schema, out, flags);
      out.append(q.includesMin() ? '[' : '{');
      Number lt = q.getMin();
      Number ut = q.getMax();
      if (lt == null) {
        out.append('*');
      } else {
        out.append(lt.toString());
      }

      out.append(" TO ");

      if (ut == null) {
        out.append('*');
      } else {
        out.append(ut.toString());
      }

      out.append(q.includesMax() ? ']' : '}');
    } else if (query instanceof BooleanQuery) {
      BooleanQuery q = (BooleanQuery) query;
      boolean needParens = false;

      if (q.getBoost() != 1.0 || q.getMinimumNumberShouldMatch() != 0 || q.isCoordDisabled()) {
        needParens = true;
      }
      if (needParens) {
        out.append('(');
      }
      boolean first = true;
      for (BooleanClause c : q.clauses()) {
        if (!first) {
          out.append(' ');
        } else {
          first = false;
        }

        if (c.isProhibited()) {
          out.append('-');
        } else if (c.isRequired()) {
          out.append('+');
        }
        Query subQuery = c.getQuery();
        boolean wrapQuery = false;

        // TODO: may need to put parens around other types
        // of queries too, depending on future syntax.
        if (subQuery instanceof BooleanQuery) {
          wrapQuery = true;
        }

        if (wrapQuery) {
          out.append('(');
        }

        toString(subQuery, schema, out, flags);

        if (wrapQuery) {
          out.append(')');
        }
      }

      if (needParens) {
        out.append(')');
      }
      if (q.getMinimumNumberShouldMatch() > 0) {
        out.append('~');
        out.append(Integer.toString(q.getMinimumNumberShouldMatch()));
      }
      if (q.isCoordDisabled()) {
        out.append("/no_coord");
      }

    } else if (query instanceof PrefixQuery) {
      PrefixQuery q = (PrefixQuery) query;
      Term prefix = q.getPrefix();
      FieldType ft = writeFieldName(prefix.field(), schema, out, flags);
      out.append(prefix.text());
      out.append('*');
    } else if (query instanceof WildcardQuery) {
      out.append(query.toString());
      writeBoost = false;
    } else if (query instanceof FuzzyQuery) {
      out.append(query.toString());
      writeBoost = false;
    } else if (query instanceof ConstantScoreQuery) {
      out.append(query.toString());
      writeBoost = false;
    } else if (query instanceof WrappedQuery) {
      WrappedQuery q = (WrappedQuery) query;
      out.append(q.getOptions());
      toString(q.getWrappedQuery(), schema, out, flags);
      writeBoost = false; // we don't use the boost on wrapped queries
    } else {
      out.append(query.getClass().getSimpleName() + '(' + query.toString() + ')');
      writeBoost = false;
    }

    if (writeBoost && query.getBoost() != 1.0f) {
      out.append("^");
      out.append(Float.toString(query.getBoost()));
    }
  }