clintropolis commented on code in PR #15974:
URL: https://github.com/apache/druid/pull/15974#discussion_r1517151732
##########
processing/src/main/java/org/apache/druid/math/expr/Function.java:
##########
@@ -3803,15 +3977,110 @@ public ExpressionType
getOutputType(Expr.InputBindingInspector inspector, List<E
}
@Override
- ExprEval doApply(ExprEval lhsExpr, ExprEval rhsExpr)
+ public ExprEval apply(List<Expr> args, Expr.ObjectBinding bindings)
{
- final Object[] array1 = lhsExpr.asArray();
- final List<Object> array2 = Arrays.asList(rhsExpr.asArray());
- boolean any = false;
+ final ExprEval arrayExpr1 = args.get(0).eval(bindings);
+ final ExprEval arrayExpr2 = args.get(1).eval(bindings);
+
+ final Object[] array1 = arrayExpr1.asArray();
+ if (array1 == null) {
+ return ExprEval.ofLong(null);
+ }
+ ExpressionType array1Type = arrayExpr1.asArrayType();
+ final Object[] array2 = arrayExpr2.castTo(array1Type).asArray();
+ if (array2 == null) {
+ return ExprEval.ofLongBoolean(false);
+ }
+ List<Object> asList = Arrays.asList(array2);
for (Object check : array1) {
- any |= array2.contains(check);
+ if (asList.contains(check)) {
+ return ExprEval.ofLongBoolean(true);
+ }
+ }
+ return ExprEval.ofLongBoolean(false);
+ }
+
+ @Override
+ public void validateArguments(List<Expr> args)
+ {
+ validationHelperCheckArgumentCount(args, 2);
+ }
+
+ @Override
+ public Set<Expr> getScalarInputs(List<Expr> args)
+ {
+ return Collections.emptySet();
+ }
+
+ @Override
+ public Set<Expr> getArrayInputs(List<Expr> args)
+ {
+ return ImmutableSet.copyOf(args);
+ }
+
+ @Override
+ public boolean hasArrayInputs()
+ {
+ return true;
+ }
+
+ @Override
+ public Function asSingleThreaded(List<Expr> args,
Expr.InputBindingInspector inspector)
+ {
+ if (args.get(1).isLiteral()) {
+ final ExpressionType lhsType = args.get(0).getOutputType(inspector);
+ if (lhsType == null) {
+ return this;
+ }
+ final ExpressionType lhsArrayType =
ExpressionType.asArrayType(lhsType);
+ final ExprEval<?> rhsEval =
args.get(1).eval(InputBindings.nilBindings());
+ final Object[] rhsArray = rhsEval.castTo(lhsArrayType).asArray();
+ if (rhsArray == null) {
+ return new ArrayOverlapFunction()
+ {
+ @Override
+ public ExprEval apply(List<Expr> args, Expr.ObjectBinding bindings)
+ {
+ final ExprEval arrayExpr1 = args.get(0).eval(bindings);
+ final Object[] array1 = arrayExpr1.asArray();
+ if (array1 == null) {
+ return ExprEval.ofLong(null);
+ }
+ return ExprEval.ofLongBoolean(false);
+ }
+ };
+ }
+ final Set<Object> set = new
ObjectAVLTreeSet<>(lhsArrayType.getElementType().getNullableStrategy());
+ set.addAll(Arrays.asList(rhsArray));
+ return new OverlapConstantArray(set);
+ }
+ return this;
+ }
+
+ private static final class OverlapConstantArray extends
ArrayContainsFunction
+ {
+ final Set<Object> set;
+
+ public OverlapConstantArray(Set<Object> set)
+ {
+ this.set = set;
+ }
+
+ @Override
+ public ExprEval apply(List<Expr> args, Expr.ObjectBinding bindings)
+ {
+ final ExprEval<?> lhsExpr = args.get(0).eval(bindings);
+ final Object[] array1 = lhsExpr.asArray();
Review Comment:
nit: `array_contains` is not an IN filter, you're thinking of
`array_overlap`, but i get the idea. I could add a 'asSingleThreaded'
optimization for these cases, `array_contains` with a scalar field and a rhs
array argument with length greater than 1 would be an 'all false unless
unknown' optimization since it could not possible contain all of the elements,
and array_overlap would be as you suggested.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]