use of org.immutables.criteria.expression.Operator in project immutables by immutables.
the class GeodeQueryVisitor method visit.
@Override
public Oql visit(Call call) {
final Operator op = call.operator();
final List<Expression> args = call.arguments();
if (op == Operators.NOT_IN || op == IterableOperators.NOT_EMPTY) {
// convert "foo not in [1, 2, 3]" into "not (foo in [1, 2, 3])"
return visit(Expressions.not(Expressions.call(inverseOp(op), call.arguments())));
}
if (op == Operators.AND || op == Operators.OR) {
Preconditions.checkArgument(!args.isEmpty(), "Size should be >=1 for %s but was %s", op, args.size());
final String join = ") " + op.name() + " (";
final String newOql = "(" + args.stream().map(a -> a.accept(this)).map(Oql::oql).collect(Collectors.joining(join)) + ")";
return new Oql(variables, newOql);
}
if (op.arity() == Operator.Arity.BINARY) {
return binaryOperator(call);
}
if (op.arity() == Operator.Arity.UNARY) {
return unaryOperator(call);
}
throw new UnsupportedOperationException("Don't know how to handle " + call);
}
use of org.immutables.criteria.expression.Operator in project immutables by immutables.
the class GeodeQueryVisitor method unaryOperator.
/**
* Operator with single operator: {@code NOT}, {@code IS_PRESENT}
*/
private Oql unaryOperator(Call call) {
final Operator op = call.operator();
final List<Expression> args = call.arguments();
Preconditions.checkArgument(args.size() == 1, "Size should be == 1 for unary operator %s but was %s", op, args.size());
Expression arg0 = args.get(0);
String path = arg0.accept(this).oql();
if (op instanceof OptionalOperators) {
// use IS_DEFINED / IS_UNDEFINED functions
String expr;
if (op == OptionalOperators.IS_PRESENT) {
expr = String.format("is_defined(%s) AND %s != null", path, path);
} else {
expr = String.format("is_undefined(%s) OR %s = null", path, path);
}
return oql(expr);
} else if (op == Operators.NOT) {
return oql(String.format("NOT (%s)", path));
} else if (op == IterableOperators.IS_EMPTY || op == StringOperators.TO_LOWER_CASE || op == StringOperators.TO_UPPER_CASE) {
return oql(String.format("%s.%s()", path, toMethodName(op)));
}
throw new UnsupportedOperationException("Unknown unary operator " + call);
}
use of org.immutables.criteria.expression.Operator in project immutables by immutables.
the class GeodeQueryVisitor method binaryOperator.
/**
* Used for operators with two arguments like {@code =}, {@code IN} etc.
*/
private Oql binaryOperator(Call call) {
final Operator op = call.operator();
final List<Expression> args = call.arguments();
Preconditions.checkArgument(args.size() == 2, "Size should be 2 for %s but was %s on call %s", op, args.size(), call);
// left node
Expression left = args.get(0);
// right node
Expression right = args.get(1);
if (op == IterableOperators.CONTAINS || op == StringOperators.MATCHES || op == StringOperators.CONTAINS || op == StringOperators.STARTS_WITH || op == StringOperators.ENDS_WITH) {
return oql(String.format("%s.%s(%s)", left.accept(this).oql(), toMethodName(op), right.accept(this).oql()));
}
if (op == StringOperators.HAS_LENGTH || op == IterableOperators.HAS_SIZE) {
return oql(String.format("%s.%s = %s", left.accept(this).oql(), toMethodName(op), right.accept(this).oql()));
}
final String operator;
if (op == Operators.EQUAL || op == Operators.NOT_EQUAL) {
operator = op == Operators.EQUAL ? "=" : "!=";
} else if (op == Operators.IN || op == Operators.NOT_IN) {
if (right instanceof Constant) {
// optimization for IN / NOT IN operators
// make constant value(s) distinct using Set
Set<Object> newValues = ImmutableSet.copyOf(Visitors.toConstant(right).values());
right = Expressions.constant(newValues);
}
operator = op == Operators.IN ? "IN" : "NOT IN";
} else if (op == ComparableOperators.GREATER_THAN) {
operator = ">";
} else if (op == ComparableOperators.GREATER_THAN_OR_EQUAL) {
operator = ">=";
} else if (op == ComparableOperators.LESS_THAN) {
operator = "<";
} else if (op == ComparableOperators.LESS_THAN_OR_EQUAL) {
operator = "<=";
} else {
throw new IllegalArgumentException("Unknown binary operator " + call);
}
return oql(String.format("%s %s %s", left.accept(this).oql(), operator, right.accept(this).oql()));
}
use of org.immutables.criteria.expression.Operator in project immutables by immutables.
the class ElasticsearchQueryVisitor method binaryCall.
private QueryBuilders.QueryBuilder binaryCall(Call call) {
final List<Expression> arguments = call.arguments();
Preconditions.checkArgument(arguments.size() == 2, "Size should be 2 for %s but was %s", call.operator(), arguments.size());
final Operator op = call.operator();
final Path path = Visitors.toPath(arguments.get(0));
final String field = pathNaming.name(path);
final Object value = Visitors.toConstant(arguments.get(1)).value();
if (op == Operators.EQUAL || op == Operators.NOT_EQUAL) {
QueryBuilders.QueryBuilder builder;
if (idPredicate.test(path)) {
// use more efficient ids query for keys
builder = QueryBuilders.idsQuery(Collections.singleton(value));
} else {
builder = QueryBuilders.termQuery(field, value);
}
if (op == Operators.NOT_EQUAL) {
QueryBuilders.BoolQueryBuilder bool = QueryBuilders.boolQuery().mustNot(builder);
if ("".equals(value)) {
// string is not empty (should also exists)
bool = bool.should(QueryBuilders.existsQuery(field));
}
builder = bool;
}
return builder;
}
if (op == Operators.IN || op == Operators.NOT_IN) {
final Collection<Object> values = ImmutableSet.copyOf(Visitors.toConstant(arguments.get(1)).values());
QueryBuilders.QueryBuilder builder;
if (idPredicate.test(path)) {
// more efficient query by ID
builder = QueryBuilders.idsQuery(values);
} else {
builder = QueryBuilders.termsQuery(field, values);
}
if (op == Operators.NOT_IN) {
builder = QueryBuilders.boolQuery().mustNot(builder);
}
return builder;
}
if (ComparableOperators.isComparable(op)) {
final QueryBuilders.RangeQueryBuilder builder = QueryBuilders.rangeQuery(field);
if (op == ComparableOperators.GREATER_THAN) {
builder.gt(value);
} else if (op == ComparableOperators.GREATER_THAN_OR_EQUAL) {
builder.gte(value);
} else if (op == ComparableOperators.LESS_THAN) {
builder.lt(value);
} else if (op == ComparableOperators.LESS_THAN_OR_EQUAL) {
builder.lte(value);
} else {
throw new UnsupportedOperationException("Unknown comparison " + call);
}
return builder;
}
if (op == StringOperators.STARTS_WITH) {
return QueryBuilders.prefixQuery(field, value.toString());
}
if (op == StringOperators.MATCHES) {
Preconditions.checkArgument(value instanceof Pattern, "%s is not regex pattern", value);
// In elastic / lucene, patterns match the entire string.
return QueryBuilders.regexpQuery(field, ((Pattern) value).pattern());
}
if (op == StringOperators.ENDS_WITH || op == StringOperators.CONTAINS) {
return QueryBuilders.wildcardQuery(field, "*" + value.toString() + (op == StringOperators.CONTAINS ? "*" : ""));
}
throw new UnsupportedOperationException(String.format("Call %s not supported", call));
}
Aggregations