/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.lucene.queryparser.flexible.standard.builders; import org.apache.lucene.document.DoublePoint; import org.apache.lucene.document.FloatPoint; import org.apache.lucene.document.IntPoint; import org.apache.lucene.document.LongPoint; import org.apache.lucene.index.PointValues; import org.apache.lucene.queryparser.flexible.core.QueryNodeException; import org.apache.lucene.queryparser.flexible.core.messages.QueryParserMessages; import org.apache.lucene.queryparser.flexible.core.nodes.QueryNode; import org.apache.lucene.queryparser.flexible.core.util.StringUtils; import org.apache.lucene.queryparser.flexible.messages.MessageImpl; import org.apache.lucene.queryparser.flexible.standard.config.PointsConfig; import org.apache.lucene.queryparser.flexible.standard.nodes.PointQueryNode; import org.apache.lucene.queryparser.flexible.standard.nodes.PointRangeQueryNode; import org.apache.lucene.search.Query; /** * Builds {@link PointValues} range queries out of {@link PointRangeQueryNode}s. * * @see PointRangeQueryNode */ public class PointRangeQueryNodeBuilder implements StandardQueryBuilder { /** * Constructs a {@link PointRangeQueryNodeBuilder} object. */ public PointRangeQueryNodeBuilder() { // empty constructor } @Override public Query build(QueryNode queryNode) throws QueryNodeException { PointRangeQueryNode numericRangeNode = (PointRangeQueryNode) queryNode; PointQueryNode lowerNumericNode = numericRangeNode.getLowerBound(); PointQueryNode upperNumericNode = numericRangeNode.getUpperBound(); Number lowerNumber = lowerNumericNode.getValue(); Number upperNumber = upperNumericNode.getValue(); PointsConfig pointsConfig = numericRangeNode.getPointsConfig(); Class<? extends Number> numberType = pointsConfig.getType(); String field = StringUtils.toString(numericRangeNode.getField()); boolean minInclusive = numericRangeNode.isLowerInclusive(); boolean maxInclusive = numericRangeNode.isUpperInclusive(); // TODO: push down cleaning up of crazy nulls and inclusive/exclusive elsewhere if (Integer.class.equals(numberType)) { Integer lower = (Integer) lowerNumber; if (lower == null) { lower = Integer.MIN_VALUE; } if (minInclusive == false) { lower = lower + 1; } Integer upper = (Integer) upperNumber; if (upper == null) { upper = Integer.MAX_VALUE; } if (maxInclusive == false) { upper = upper - 1; } return IntPoint.newRangeQuery(field, lower, upper); } else if (Long.class.equals(numberType)) { Long lower = (Long) lowerNumber; if (lower == null) { lower = Long.MIN_VALUE; } if (minInclusive == false) { lower = lower + 1; } Long upper = (Long) upperNumber; if (upper == null) { upper = Long.MAX_VALUE; } if (maxInclusive == false) { upper = upper - 1; } return LongPoint.newRangeQuery(field, lower, upper); } else if (Float.class.equals(numberType)) { Float lower = (Float) lowerNumber; if (lower == null) { lower = Float.NEGATIVE_INFINITY; } if (minInclusive == false) { lower = Math.nextUp(lower); } Float upper = (Float) upperNumber; if (upper == null) { upper = Float.POSITIVE_INFINITY; } if (maxInclusive == false) { upper = Math.nextDown(upper); } return FloatPoint.newRangeQuery(field, lower, upper); } else if (Double.class.equals(numberType)) { Double lower = (Double) lowerNumber; if (lower == null) { lower = Double.NEGATIVE_INFINITY; } if (minInclusive == false) { lower = Math.nextUp(lower); } Double upper = (Double) upperNumber; if (upper == null) { upper = Double.POSITIVE_INFINITY; } if (maxInclusive == false) { upper = Math.nextDown(upper); } return DoublePoint.newRangeQuery(field, lower, upper); } else { throw new QueryNodeException(new MessageImpl(QueryParserMessages.UNSUPPORTED_NUMERIC_DATA_TYPE, numberType)); } } }