if (!optimize) {
throw new UnsupportedOperationException("IN predicate value list type not yet implemented: " + valueListExpression.getClass().getName());
}
return node;
}
InListExpression valueList = (InListExpression) valueListExpression;
Set<Object> set = inListCache.get(valueList);
// We use the presence of the node in the map to indicate that we've already done
// the analysis below. If the value is null, it means that we can't apply the HashSet
// optimization
if (!inListCache.containsKey(valueList)) {
if (Iterables.all(valueList.getValues(), isNonNullLiteralPredicate())) {
// if all elements are constant, create a set with them
set = new HashSet<>();
for (Expression expression : valueList.getValues()) {
set.add(process(expression, context));
}
}
inListCache.put(valueList, set);
}
if (set != null && !(value instanceof Expression)) {
return set.contains(value);
}
boolean hasUnresolvedValue = false;
if (value instanceof Expression) {
hasUnresolvedValue = true;
}
boolean hasNullValue = false;
boolean found = false;
List<Object> values = new ArrayList<>(valueList.getValues().size());
List<Type> types = new ArrayList<>(valueList.getValues().size());
for (Expression expression : valueList.getValues()) {
Object inValue = process(expression, context);
if (value instanceof Expression || inValue instanceof Expression) {
hasUnresolvedValue = true;
values.add(inValue);
types.add(expressionTypes.get(expression));
continue;
}
if (inValue == null) {
hasNullValue = true;
}
else if (!found && (Boolean) invokeOperator(OperatorType.EQUAL, types(node.getValue(), expression), ImmutableList.of(value, inValue))) {
// in does not short-circuit so we must evaluate all value in the list
found = true;
}
}
if (found) {
return true;
}
if (hasUnresolvedValue) {
Type type = expressionTypes.get(node.getValue());
return new InPredicate(toExpression(value, type), new InListExpression(toExpressions(values, types)));
}
if (hasNullValue) {
return null;
}
return false;