Skip to content
This repository was archived by the owner on May 28, 2026. It is now read-only.
This repository was archived by the owner on May 28, 2026. It is now read-only.

Replace Query infrastructure with Hazelcast SQL #147

Description

@pivovarit

Once SQL support is production-ready, we should remove our custom querying infrastructure and reuse what's already in Hazelcast

case ENDING_WITH:
case LIKE:
case NOT_LIKE:
return fromLikeVariant(type, ignoreCase, property, iterator);
case TRUE:
case FALSE:
return fromBooleanVariant(type, property);
case SIMPLE_PROPERTY:
case NEGATING_SIMPLE_PROPERTY:
return fromEqualityVariant(type, ignoreCase, property, iterator);
case REGEX:
return Predicates.regex(property, iterator.next().toString());
case IS_EMPTY:
case IS_NOT_EMPTY:
return fromEmptyVariant(type, property);
/* case EXISTS:*/
case NEAR:
case WITHIN:
return fromGeoVariant(type, property, iterator);
default:
throw new InvalidDataAccessApiUsageException(String.format("Unsupported type '%s'", type));
}
}
private Predicate<?, ?> fromBooleanVariant(Type type, String property) {
switch (type) {
case TRUE:
return Predicates.equal(property, true);
case FALSE:
return Predicates.equal(property, false);
default:
throw new InvalidDataAccessApiUsageException(String.format("Logic error for '%s' in query", type));
}
}
private Predicate<?, ?> fromCollectionVariant(Type type, String property, Iterator<Comparable<?>> iterator) {
switch (type) {
case IN:
return Predicates.in(property, collectToArray(type, iterator));
case NOT_IN:
return Predicates.not(Predicates.in(property, collectToArray(type, iterator)));
default:
throw new InvalidDataAccessApiUsageException(String.format("Logic error for '%s' in query", type));
}
}
private Predicate<?, ?> fromInequalityVariant(Type type, String property, Iterator<Comparable<?>> iterator) {
switch (type) {
case AFTER:
case GREATER_THAN:
return Predicates.greaterThan(property, iterator.next());
case GREATER_THAN_EQUAL:
return Predicates.greaterEqual(property, iterator.next());
case BEFORE:
case LESS_THAN:
return Predicates.lessThan(property, iterator.next());
case LESS_THAN_EQUAL:
return Predicates.lessEqual(property, iterator.next());
case BETWEEN:
Comparable<?> first = iterator.next();
Comparable<?> second = iterator.next();
return Predicates.between(property, first, second);
default:
throw new InvalidDataAccessApiUsageException(String.format("Logic error for '%s' in query", type));
}
}
private Predicate<?, ?> fromNullVariant(Type type, String property) {
switch (type) {
case IS_NULL:
return Predicates.equal(property, null);
case IS_NOT_NULL:
return Predicates.notEqual(property, null);
default:
throw new InvalidDataAccessApiUsageException(String.format("Logic error for '%s' in query", type));
}
}
private Predicate<?, ?> fromEqualityVariant(Type type, boolean ignoreCase, String property,
Iterator<Comparable<?>> iterator) {
switch (type) {
case SIMPLE_PROPERTY:
if (ignoreCase) {
return Predicates.ilike(property, iterator.next().toString());
} else {
return Predicates.equal(property, iterator.next());
}
case NEGATING_SIMPLE_PROPERTY:
if (ignoreCase) {
return Predicates.not(Predicates.ilike(property, iterator.next().toString()));
} else {
return Predicates.notEqual(property, iterator.next());
}
default:
throw new InvalidDataAccessApiUsageException(String.format("Logic error for '%s' in query", type));
}
}
private Predicate<?, ?> fromLikeVariant(Type type, boolean ignoreCase, String property, Iterator<Comparable<?>> iterator) {
String likeExpression = iterator.next().toString();
switch (type) {
case CONTAINING:
case NOT_CONTAINING:
likeExpression = String.join("", "%", likeExpression, "%");
break;
case STARTING_WITH:
likeExpression = String.join("", likeExpression, "%");
break;
case ENDING_WITH:
likeExpression = String.join("", "%", likeExpression);
break;
case LIKE:
case NOT_LIKE:
break;
default:
throw new InvalidDataAccessApiUsageException(String.format("'%s' is not supported for LIKE style query", type));
}
Predicate likePredicate = ignoreCase ? Predicates.ilike(property, likeExpression) : Predicates
.like(property, likeExpression);
return type.equals(NOT_LIKE) || type.equals(NOT_CONTAINING) ? Predicates.not(likePredicate) : likePredicate;
}
private boolean ifIgnoreCase(Part part) {
switch (part.shouldIgnoreCase()) {
case ALWAYS:
Assert.state(canUpperCase(part.getProperty()),
String.format("Unable to ignore case of %s types, the property '%s' must reference a String",
part.getProperty().getType().getName(), part.getProperty().getSegment()));
return true;
case WHEN_POSSIBLE:
return canUpperCase(part.getProperty());
case NEVER:
default:
return false;
}
}
private boolean canUpperCase(PropertyPath path) {
return String.class.equals(path.getType());
}
private boolean isCollection(Object item) {
return Collection.class.isAssignableFrom(item.getClass());
}
private Comparable<?>[] collectToArray(Type type, Iterator<Comparable<?>> iterator) {
Object item = iterator.next();
Assert.state(isCollection(item), String.format("%s requires collection of values", type));
Collection<Comparable<?>> itemcol = (Collection<Comparable<?>>) item;
return itemcol.toArray(new Comparable<?>[0]);
}
private Predicate<?, ?> fromEmptyVariant(Type type, String property) {
switch (type) {
case IS_EMPTY:
return Predicates.equal(property, "");
case IS_NOT_EMPTY:
return Predicates.notEqual(property, "");
default:
throw new InvalidDataAccessApiUsageException(String.format("Logic error for '%s' in query", type));
}
}
private Predicate<?, ?> fromGeoVariant(Type type, String property, Iterator<Comparable<?>> iterator) {
final Object item = iterator.next();
Point point;
Distance distance;
if (item instanceof Point) {
point = (Point) item;
if (!iterator.hasNext()) {
throw new InvalidDataAccessApiUsageException(
"Expected to find distance value for geo query. Are you missing a parameter?");
}
Object distObject = iterator.next();
if (distObject instanceof Distance) {
distance = (Distance) distObject;
} else if (distObject instanceof Number) {
distance = new Distance(((Number) distObject).doubleValue(), Metrics.KILOMETERS);
} else {
throw new InvalidDataAccessApiUsageException(String
.format("Expected to find Distance or Numeric value for geo query but was %s.",
distObject.getClass()));
}
} else if (item instanceof Circle) {
point = ((Circle) item).getCenter();
distance = ((Circle) item).getRadius();
} else {
throw new InvalidDataAccessApiUsageException(
String.format("Expected to find a Circle or Point/Distance for geo query but was %s.", item.getClass()));
}
switch (type) {
case WITHIN:
case NEAR:
return new GeoPredicate<>(property, point, distance);
default:
throw new InvalidDataAccessApiUsageException(String.format("Logic error for '%s' in query", type));
}
}

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions