github-advanced-security[bot] commented on code in PR #18084:
URL: https://github.com/apache/druid/pull/18084#discussion_r2130594671
##########
processing/src/main/java/org/apache/druid/math/expr/Function.java:
##########
@@ -4157,6 +4158,300 @@
}
}
+ class MvOverlapFunction implements Function
+ {
+ @Override
+ public String name()
+ {
+ return "mv_overlap";
+ }
+
+ @Nullable
+ @Override
+ public ExpressionType getOutputType(Expr.InputBindingInspector inspector,
List<Expr> args)
+ {
+ return ExpressionType.LONG;
+ }
+
+ @Override
+ public ExprEval apply(List<Expr> args, Expr.ObjectBinding bindings)
+ {
+ final ExprEval<?> arg1 =
Function.harmonizeMultiValue(args.get(0).eval(bindings));
+ final ExprEval<?> arg2 = args.get(1).eval(bindings);
+
+ // Cast arg1 to arg2's type.
+ final Object[] array2 = arg2.asArray();
+ final ExpressionType array2Type = arg2.asArrayType();
+ final Object[] array1 = arg1.castTo(array2Type).asArray();
+
+ // If the second argument is null, check if the first argument contains
null.
+ if (array2 == null) {
+ return ExprEval.ofLongBoolean(arrayContainsNull(array1));
+ }
+
+ // If the second argument is empty array, return false regardless of
first argument.
+ if (array2.length == 0) {
+ return ExprEval.ofLongBoolean(false);
+ }
+
+ // Check for overlap.
+ final Set<Object> set2 = new ObjectOpenHashSet<>(array2);
+ for (final Object check : array1) {
+ if (set2.contains(check)) {
+ return ExprEval.ofLongBoolean(true);
+ }
+ }
+
+ // No overlap.
+ if (!set2.contains(null) && arrayContainsNull(array1)) {
+ return ExprEval.ofLong(null);
+ } else {
+ 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
Review Comment:
## Unread local variable
Variable 'Expr arg1' is never read.
[Show more
details](https://github.com/apache/druid/security/code-scanning/9209)
##########
processing/src/main/java/org/apache/druid/math/expr/Function.java:
##########
@@ -4157,6 +4158,300 @@
}
}
+ class MvOverlapFunction implements Function
+ {
+ @Override
+ public String name()
+ {
+ return "mv_overlap";
+ }
+
+ @Nullable
+ @Override
+ public ExpressionType getOutputType(Expr.InputBindingInspector inspector,
List<Expr> args)
+ {
+ return ExpressionType.LONG;
+ }
+
+ @Override
+ public ExprEval apply(List<Expr> args, Expr.ObjectBinding bindings)
+ {
+ final ExprEval<?> arg1 =
Function.harmonizeMultiValue(args.get(0).eval(bindings));
+ final ExprEval<?> arg2 = args.get(1).eval(bindings);
+
+ // Cast arg1 to arg2's type.
+ final Object[] array2 = arg2.asArray();
+ final ExpressionType array2Type = arg2.asArrayType();
+ final Object[] array1 = arg1.castTo(array2Type).asArray();
+
+ // If the second argument is null, check if the first argument contains
null.
+ if (array2 == null) {
+ return ExprEval.ofLongBoolean(arrayContainsNull(array1));
+ }
+
+ // If the second argument is empty array, return false regardless of
first argument.
+ if (array2.length == 0) {
+ return ExprEval.ofLongBoolean(false);
+ }
+
+ // Check for overlap.
+ final Set<Object> set2 = new ObjectOpenHashSet<>(array2);
+ for (final Object check : array1) {
+ if (set2.contains(check)) {
+ return ExprEval.ofLongBoolean(true);
+ }
+ }
+
+ // No overlap.
+ if (!set2.contains(null) && arrayContainsNull(array1)) {
+ return ExprEval.ofLong(null);
+ } else {
+ 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)
+ {
+ final Expr arg1 = args.get(0);
+ final Expr arg2 = args.get(1);
+
+ if (arg2.isLiteral()) {
+ final ExprEval<?> rhsEval =
args.get(1).eval(InputBindings.nilBindings());
+ final Object[] rhsArray = rhsEval.asArray();
+
+ if (rhsArray == null) {
+ return new MvOverlapConstantNull();
+ } else if (rhsArray.length == 0) {
+ return new MvOverlapConstantEmpty();
+ } else if (rhsEval.elementType().isPrimitive()) {
+ return new MvOverlapConstantArray(
+ new ObjectOpenHashSet<>(rhsArray),
+ arrayContainsNull(rhsArray),
+ rhsEval.asArrayType()
+ );
+ }
+ }
+
+ return this;
+ }
+
+ private static final class MvOverlapConstantNull extends MvOverlapFunction
+ {
+ @Override
+ public ExprEval<?> apply(List<Expr> args, Expr.ObjectBinding bindings)
+ {
+ final ExprEval<?> arrayExpr1 =
Function.harmonizeMultiValue(args.get(0).eval(bindings));
+ return ExprEval.ofLongBoolean(arrayContainsNull(arrayExpr1.asArray()));
+ }
+ }
+
+ private static final class MvOverlapConstantEmpty extends MvOverlapFunction
+ {
+ @Override
+ public ExprEval<?> apply(List<Expr> args, Expr.ObjectBinding bindings)
+ {
+ return ExprEval.ofLongBoolean(false);
+ }
+ }
+
+ private static final class MvOverlapConstantArray extends MvOverlapFunction
+ {
+ final Set<Object> matchValues;
+ final boolean rhsHasNull;
+ final ExpressionType matchArrayType;
+
+ public MvOverlapConstantArray(Set<Object> matchValues, boolean
rhsHasNull, ExpressionType matchArrayType)
+ {
+ this.matchValues = matchValues;
+ this.rhsHasNull = rhsHasNull;
+ this.matchArrayType = matchArrayType;
+ }
+
+ @Override
+ public ExprEval<?> apply(List<Expr> args, Expr.ObjectBinding bindings)
+ {
+ final ExprEval<?> arrayExpr1 =
Function.harmonizeMultiValue(args.get(0).eval(bindings));
+ final Object[] array1 = arrayExpr1.castTo(matchArrayType).asArray();
+
+ for (final Object check : array1) {
+ if (matchValues.contains(check)) {
+ return ExprEval.ofLongBoolean(true);
+ }
+ }
+
+ // No overlap.
+ if (!rhsHasNull && arrayContainsNull(array1)) {
+ return ExprEval.ofLong(null);
+ } else {
+ return ExprEval.ofLongBoolean(false);
+ }
+ }
+ }
+ }
+
+ class MvContainsFunction implements Function
+ {
+ @Override
+ public String name()
+ {
+ return "mv_contains";
+ }
+
+ @Nullable
+ @Override
+ public ExpressionType getOutputType(Expr.InputBindingInspector inspector,
List<Expr> args)
+ {
+ return ExpressionType.LONG;
+ }
+
+ @Override
+ public ExprEval apply(List<Expr> args, Expr.ObjectBinding bindings)
+ {
+ final ExprEval<?> arg1 =
Function.harmonizeMultiValue(args.get(0).eval(bindings));
+ final ExprEval<?> arg2 = args.get(1).eval(bindings);
+
+ // Cast arg1 to arg2's type.
+ final Object[] array2 = arg2.asArray();
+ final ExpressionType array2Type = arg2.asArrayType();
+ final Object[] array1 = arg1.castTo(array2Type).asArray();
+
+ // If the second argument is null, check if the first argument contains
null.
+ if (array2 == null) {
+ return ExprEval.ofLongBoolean(arrayContainsNull(array1));
+ }
+
+ // If the second argument is an empty array, return true regardless of
the first argument.
+ if (array2.length == 0) {
+ return ExprEval.ofLongBoolean(true);
+ }
+
+ return
ExprEval.ofLongBoolean(Arrays.asList(array1).containsAll(Arrays.asList(array2)));
+ }
+
+ @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
Review Comment:
## Unread local variable
Variable 'Expr arg1' is never read.
[Show more
details](https://github.com/apache/druid/security/code-scanning/9210)
--
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]