use of org.neo4j.internal.kernel.api.PropertyIndexQuery.RangePredicate in project neo4j by neo4j.
the class GenericNativeIndexReader method initializeRangeForGeometrySubQuery.
/**
* Initializes {@code treeKeyFrom} and {@code treeKeyTo} from the {@link PropertyIndexQuery query}.
* Geometry range queries makes an otherwise straight-forward key construction complex in that a geometry range internally is performed
* by executing multiple sub-range queries to the index. Each of those sub-range queries still needs to construct the full composite key -
* in the case of a composite index. Therefore this method can be called either with null or non-null {@code crs} and {@code range} and
* constructing a key when coming across a {@link PropertyIndexQuery.GeometryRangePredicate} will use the provided crs/range instead
* of the predicate, where the specific range is one out of many sub-ranges calculated from the {@link PropertyIndexQuery.GeometryRangePredicate}
* by the caller.
*
* @param treeKeyFrom the "from" key to construct from the query.
* @param treeKeyTo the "to" key to construct from the query.
* @param query the query to construct keys from to later send to {@link GBPTree} when reading.
* @param crs {@link CoordinateReferenceSystem} for the specific {@code range}, if range is specified too.
* @param range sub-range of a larger {@link PropertyIndexQuery.GeometryRangePredicate} to use instead of {@link PropertyIndexQuery.GeometryRangePredicate}
* in the query.
* @return {@code true} if filtering is needed for the results from the reader, otherwise {@code false}.
*/
private static boolean initializeRangeForGeometrySubQuery(GenericKey treeKeyFrom, GenericKey treeKeyTo, PropertyIndexQuery[] query, CoordinateReferenceSystem crs, SpaceFillingCurve.LongRange range) {
boolean needsFiltering = false;
for (int i = 0; i < query.length; i++) {
PropertyIndexQuery predicate = query[i];
switch(predicate.type()) {
case exists:
treeKeyFrom.initValueAsLowest(i, ValueGroup.UNKNOWN);
treeKeyTo.initValueAsHighest(i, ValueGroup.UNKNOWN);
break;
case exact:
ExactPredicate exactPredicate = (ExactPredicate) predicate;
treeKeyFrom.initFromValue(i, exactPredicate.value(), NEUTRAL);
treeKeyTo.initFromValue(i, exactPredicate.value(), NEUTRAL);
break;
case range:
if (isGeometryRangeQuery(predicate)) {
// Use the supplied SpaceFillingCurve range instead of the GeometryRangePredicate because at the time of calling this method
// the original geometry range have been split up into multiple sub-ranges and this invocation is for one of those sub-ranges.
// We can not take query inclusion / exclusion into consideration here because then we risk missing border values. Always use
// Inclusion.LOW / HIGH respectively and filter out points later on.
treeKeyFrom.stateSlot(i).writePointDerived(crs, range.min, LOW);
treeKeyTo.stateSlot(i).writePointDerived(crs, range.max + 1, HIGH);
needsFiltering = true;
} else {
RangePredicate<?> rangePredicate = (RangePredicate<?>) predicate;
initFromForRange(i, rangePredicate, treeKeyFrom);
initToForRange(i, rangePredicate, treeKeyTo);
}
break;
case stringPrefix:
StringPrefixPredicate prefixPredicate = (StringPrefixPredicate) predicate;
treeKeyFrom.stateSlot(i).initAsPrefixLow(prefixPredicate.prefix());
treeKeyTo.stateSlot(i).initAsPrefixHigh(prefixPredicate.prefix());
break;
case stringSuffix:
case stringContains:
treeKeyFrom.initValueAsLowest(i, ValueGroup.TEXT);
treeKeyTo.initValueAsHighest(i, ValueGroup.TEXT);
needsFiltering = true;
break;
default:
throw new IllegalArgumentException("IndexQuery of type " + predicate.type() + " is not supported.");
}
}
return needsFiltering;
}
Aggregations