Skip to content

Commit

Permalink
Fallback vectorization for FunctionExpr and BaseMacroFunctionExpr.
Browse files Browse the repository at this point in the history
This patch adds FallbackVectorProcessor, a processor that adapts non-vectorizable
operations into vectorizable ones. It is used in FunctionExpr and BaseMacroFunctionExpr.

In addition:

- Identifiers are updated to offer getObjectVector for ARRAY and COMPLEX in addition
  to STRING. ExprEvalObjectVector is updated to offer ARRAY and COMPLEX as well.

- In SQL tests, cannotVectorize now fails tests if an exception is not thrown. This makes
  it easier to identify tests that can now vectorize.

- Fix a null-matcher bug in StringObjectVectorValueMatcher.
  • Loading branch information
gianm committed May 1, 2024
1 parent 5d1950d commit 2c3925a
Show file tree
Hide file tree
Showing 23 changed files with 793 additions and 328 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import org.apache.druid.java.util.common.StringUtils;
import org.apache.druid.math.expr.vector.ExprVectorProcessor;
import org.apache.druid.math.expr.vector.FallbackVectorProcessor;

import javax.annotation.Nullable;
import java.util.Collections;
Expand Down Expand Up @@ -158,6 +160,18 @@ public BindingAnalysis analyzeInputs()
return analyzeInputsSupplier.get();
}

@Override
public boolean canVectorize(InputBindingInspector inspector)
{
return getOutputType(inspector) != null && inspector.canVectorize(args);
}

@Override
public <T> ExprVectorProcessor<T> asVectorProcessor(VectorInputBindingInspector inspector)
{
return FallbackVectorProcessor.create(macro, args, inspector);
}

/**
* Implemented by subclasses to provide the value for {@link #analyzeInputs()}, which uses a memoized supplier.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.apache.druid.error.DruidException;
import org.apache.druid.java.util.common.StringUtils;
import org.apache.druid.math.expr.vector.ExprVectorProcessor;
import org.apache.druid.math.expr.vector.FallbackVectorProcessor;
import org.apache.druid.segment.column.Types;

import javax.annotation.Nullable;
Expand Down Expand Up @@ -223,13 +224,18 @@ public ExprEval eval(ObjectBinding bindings)
@Override
public boolean canVectorize(InputBindingInspector inspector)
{
return function.canVectorize(inspector, args);
return function.canVectorize(inspector, args)
|| (getOutputType(inspector) != null && inspector.canVectorize(args));
}

@Override
public ExprVectorProcessor<?> asVectorProcessor(VectorInputBindingInspector inspector)
{
return function.asVectorProcessor(inspector, args);
if (function.canVectorize(inspector, args)) {
return function.asVectorProcessor(inspector, args);
} else {
return FallbackVectorProcessor.create(function, args, inspector);
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public ExprEvalVector<Object[]> evalVector(Expr.VectorInputBinding bindings)
for (int i = 0; i < objects.length; i++) {
output[i] = Evals.asString(objects[i]);
}
return new ExprEvalObjectVector(output);
return new ExprEvalObjectVector(output, ExpressionType.STRING);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@
package org.apache.druid.math.expr.vector;

import org.apache.druid.common.config.NullHandling;
import org.apache.druid.error.DruidException;
import org.apache.druid.math.expr.Evals;
import org.apache.druid.math.expr.ExprEval;
import org.apache.druid.math.expr.ExprType;
import org.apache.druid.math.expr.ExpressionType;

import javax.annotation.Nullable;
Expand All @@ -36,9 +38,17 @@ public final class ExprEvalObjectVector extends ExprEvalVector<Object[]>
@Nullable
private boolean[] numericNulls;

public ExprEvalObjectVector(Object[] values)
private final ExpressionType type;

public ExprEvalObjectVector(Object[] values, ExpressionType type)
{
super(values, null);
this.type = type;

if (type.isNumeric()) {
// Cannot use ExprEvalObjectSelector on types that are innately numbers.
throw DruidException.defensive("Expression of type[%s] is numeric", type);
}
}

private void computeNumbers()
Expand All @@ -47,16 +57,25 @@ private void computeNumbers()
longs = new long[values.length];
doubles = new double[values.length];
numericNulls = new boolean[values.length];
boolean isString = type.is(ExprType.STRING);
for (int i = 0; i < values.length; i++) {
Number n = ExprEval.computeNumber(Evals.asString(values[i]));
if (n != null) {
longs[i] = n.longValue();
doubles[i] = n.doubleValue();
numericNulls[i] = false;
if (isString) {
Number n = ExprEval.computeNumber(Evals.asString(values[i]));
if (n != null) {
longs[i] = n.longValue();
doubles[i] = n.doubleValue();
numericNulls[i] = false;
} else {
longs[i] = 0L;
doubles[i] = 0.0;
numericNulls[i] = NullHandling.sqlCompatible();
}
} else {
longs[i] = 0L;
doubles[i] = 0.0;
numericNulls[i] = NullHandling.sqlCompatible();
// ARRAY, COMPLEX
final ExprEval<?> valueEval = ExprEval.bestEffortOf(values[i]);
longs[i] = valueEval.asLong();
doubles[i] = valueEval.asDouble();
numericNulls[i] = valueEval.isNumericNull();
}
}
}
Expand All @@ -73,7 +92,7 @@ public boolean[] getNullVector()
@Override
public ExpressionType getType()
{
return ExpressionType.STRING;
return type;
}

@Override
Expand Down

0 comments on commit 2c3925a

Please sign in to comment.