mirror of https://github.com/apache/druid.git
use object[] instead of string[] for vector expressions to be consistent with vector object selectors (#13209)
* use object[] instead of string[] for vector expressions to be consistent with vector object selectors * simplify
This commit is contained in:
parent
80e10ffe22
commit
59e2afc566
|
@ -23,12 +23,11 @@ import org.apache.commons.lang.StringEscapeUtils;
|
||||||
import org.apache.druid.java.util.common.StringUtils;
|
import org.apache.druid.java.util.common.StringUtils;
|
||||||
import org.apache.druid.math.expr.vector.ExprEvalDoubleVector;
|
import org.apache.druid.math.expr.vector.ExprEvalDoubleVector;
|
||||||
import org.apache.druid.math.expr.vector.ExprEvalLongVector;
|
import org.apache.druid.math.expr.vector.ExprEvalLongVector;
|
||||||
import org.apache.druid.math.expr.vector.ExprEvalStringVector;
|
import org.apache.druid.math.expr.vector.ExprEvalObjectVector;
|
||||||
import org.apache.druid.math.expr.vector.ExprEvalVector;
|
import org.apache.druid.math.expr.vector.ExprEvalVector;
|
||||||
import org.apache.druid.math.expr.vector.ExprVectorProcessor;
|
import org.apache.druid.math.expr.vector.ExprVectorProcessor;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -158,15 +157,12 @@ class IdentifierExpr implements Expr
|
||||||
if (inputType == null) {
|
if (inputType == null) {
|
||||||
// nil column, we can be anything, so be a string because it's the most flexible
|
// nil column, we can be anything, so be a string because it's the most flexible
|
||||||
// (numbers will be populated with default values in default mode and non-null)
|
// (numbers will be populated with default values in default mode and non-null)
|
||||||
return new IdentifierVectorProcessor<String[]>(ExpressionType.STRING)
|
return new IdentifierVectorProcessor<Object[]>(ExpressionType.STRING)
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public ExprEvalVector<String[]> evalVector(VectorInputBinding bindings)
|
public ExprEvalVector<Object[]> evalVector(VectorInputBinding bindings)
|
||||||
{
|
{
|
||||||
// need to cast to string[] because null columns come out as object[]
|
return new ExprEvalObjectVector(bindings.getObjectVector(binding));
|
||||||
return new ExprEvalStringVector(
|
|
||||||
Arrays.stream(bindings.getObjectVector(binding)).map(x -> (String) x).toArray(String[]::new)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -190,12 +186,12 @@ class IdentifierExpr implements Expr
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
case STRING:
|
case STRING:
|
||||||
return new IdentifierVectorProcessor<String[]>(inputType)
|
return new IdentifierVectorProcessor<Object[]>(inputType)
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public ExprEvalVector<String[]> evalVector(VectorInputBinding bindings)
|
public ExprEvalVector<Object[]> evalVector(VectorInputBinding bindings)
|
||||||
{
|
{
|
||||||
return new ExprEvalStringVector(bindings.getObjectVector(binding));
|
return new ExprEvalObjectVector(bindings.getObjectVector(binding));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -23,7 +23,7 @@ import org.apache.druid.math.expr.Evals;
|
||||||
import org.apache.druid.math.expr.Expr;
|
import org.apache.druid.math.expr.Expr;
|
||||||
import org.apache.druid.math.expr.ExpressionType;
|
import org.apache.druid.math.expr.ExpressionType;
|
||||||
|
|
||||||
public final class CastToStringVectorProcessor extends CastToTypeVectorProcessor<String[]>
|
public final class CastToStringVectorProcessor extends CastToTypeVectorProcessor<Object[]>
|
||||||
{
|
{
|
||||||
public CastToStringVectorProcessor(ExprVectorProcessor<?> delegate)
|
public CastToStringVectorProcessor(ExprVectorProcessor<?> delegate)
|
||||||
{
|
{
|
||||||
|
@ -31,15 +31,15 @@ public final class CastToStringVectorProcessor extends CastToTypeVectorProcessor
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ExprEvalVector<String[]> evalVector(Expr.VectorInputBinding bindings)
|
public ExprEvalVector<Object[]> evalVector(Expr.VectorInputBinding bindings)
|
||||||
{
|
{
|
||||||
ExprEvalVector<?> result = delegate.evalVector(bindings);
|
ExprEvalVector<?> result = delegate.evalVector(bindings);
|
||||||
final Object[] objects = result.getObjectVector();
|
final Object[] objects = result.getObjectVector();
|
||||||
final String[] output = new String[objects.length];
|
final Object[] output = new String[objects.length];
|
||||||
for (int i = 0; i < objects.length; i++) {
|
for (int i = 0; i < objects.length; i++) {
|
||||||
output[i] = Evals.asString(objects[i]);
|
output[i] = Evals.asString(objects[i]);
|
||||||
}
|
}
|
||||||
return new ExprEvalStringVector(output);
|
return new ExprEvalObjectVector(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -20,12 +20,13 @@
|
||||||
package org.apache.druid.math.expr.vector;
|
package org.apache.druid.math.expr.vector;
|
||||||
|
|
||||||
import org.apache.druid.common.config.NullHandling;
|
import org.apache.druid.common.config.NullHandling;
|
||||||
|
import org.apache.druid.math.expr.Evals;
|
||||||
import org.apache.druid.math.expr.ExprEval;
|
import org.apache.druid.math.expr.ExprEval;
|
||||||
import org.apache.druid.math.expr.ExpressionType;
|
import org.apache.druid.math.expr.ExpressionType;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public final class ExprEvalStringVector extends ExprEvalVector<String[]>
|
public final class ExprEvalObjectVector extends ExprEvalVector<Object[]>
|
||||||
{
|
{
|
||||||
@Nullable
|
@Nullable
|
||||||
private long[] longs;
|
private long[] longs;
|
||||||
|
@ -35,7 +36,7 @@ public final class ExprEvalStringVector extends ExprEvalVector<String[]>
|
||||||
@Nullable
|
@Nullable
|
||||||
private boolean[] numericNulls;
|
private boolean[] numericNulls;
|
||||||
|
|
||||||
public ExprEvalStringVector(String[] values)
|
public ExprEvalObjectVector(Object[] values)
|
||||||
{
|
{
|
||||||
super(values, null);
|
super(values, null);
|
||||||
}
|
}
|
||||||
|
@ -47,7 +48,7 @@ public final class ExprEvalStringVector extends ExprEvalVector<String[]>
|
||||||
doubles = new double[values.length];
|
doubles = new double[values.length];
|
||||||
numericNulls = new boolean[values.length];
|
numericNulls = new boolean[values.length];
|
||||||
for (int i = 0; i < values.length; i++) {
|
for (int i = 0; i < values.length; i++) {
|
||||||
Number n = ExprEval.computeNumber(values[i]);
|
Number n = ExprEval.computeNumber(Evals.asString(values[i]));
|
||||||
if (n != null) {
|
if (n != null) {
|
||||||
longs[i] = n.longValue();
|
longs[i] = n.longValue();
|
||||||
doubles[i] = n.doubleValue();
|
doubles[i] = n.doubleValue();
|
|
@ -29,7 +29,7 @@ import java.lang.reflect.Array;
|
||||||
* Result of {@link ExprVectorProcessor#evalVector} which wraps the actual evaluated results of the operation over the
|
* Result of {@link ExprVectorProcessor#evalVector} which wraps the actual evaluated results of the operation over the
|
||||||
* input vector(s). Methods to get actual results mirror vectorized value and object selectors.
|
* input vector(s). Methods to get actual results mirror vectorized value and object selectors.
|
||||||
*
|
*
|
||||||
* The generic parameter T should be the native java array type of the vector result (long[], String[], etc.)
|
* The generic parameter T should be the native java array type of the vector result (long[], Object[], etc.)
|
||||||
*/
|
*/
|
||||||
public abstract class ExprEvalVector<T>
|
public abstract class ExprEvalVector<T>
|
||||||
{
|
{
|
||||||
|
|
|
@ -22,14 +22,21 @@ package org.apache.druid.math.expr.vector;
|
||||||
import org.apache.druid.math.expr.ExpressionType;
|
import org.apache.druid.math.expr.ExpressionType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* specialized {@link UnivariateFunctionVectorObjectProcessor} for processing (String[]) -> long[]
|
* specialized {@link UnivariateFunctionVectorObjectProcessor} for processing (Object[]) -> long[]
|
||||||
*/
|
*/
|
||||||
public abstract class LongOutStringInFunctionVectorProcessor
|
public abstract class LongOutObjectInFunctionVectorProcessor
|
||||||
extends UnivariateFunctionVectorObjectProcessor<String[], long[]>
|
extends UnivariateFunctionVectorObjectProcessor<Object[], long[]>
|
||||||
{
|
{
|
||||||
public LongOutStringInFunctionVectorProcessor(ExprVectorProcessor<String[]> processor, int maxVectorSize)
|
final ExpressionType inputType;
|
||||||
|
|
||||||
|
public LongOutObjectInFunctionVectorProcessor(
|
||||||
|
ExprVectorProcessor<Object[]> processor,
|
||||||
|
int maxVectorSize,
|
||||||
|
ExpressionType inputType
|
||||||
|
)
|
||||||
{
|
{
|
||||||
super(CastToTypeVectorProcessor.cast(processor, ExpressionType.STRING), maxVectorSize, new long[maxVectorSize]);
|
super(CastToTypeVectorProcessor.cast(processor, inputType), maxVectorSize, new long[maxVectorSize]);
|
||||||
|
this.inputType = inputType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
|
@ -23,19 +23,21 @@ import org.apache.druid.math.expr.ExpressionType;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public abstract class LongOutStringsInFunctionVectorProcessor extends BivariateFunctionVectorObjectProcessor<String[], String[], long[]>
|
public abstract class LongOutObjectsInFunctionVectorProcessor
|
||||||
|
extends BivariateFunctionVectorObjectProcessor<Object[], Object[], long[]>
|
||||||
{
|
{
|
||||||
private final boolean[] outNulls;
|
private final boolean[] outNulls;
|
||||||
|
|
||||||
protected LongOutStringsInFunctionVectorProcessor(
|
protected LongOutObjectsInFunctionVectorProcessor(
|
||||||
ExprVectorProcessor<String[]> left,
|
ExprVectorProcessor<Object[]> left,
|
||||||
ExprVectorProcessor<String[]> right,
|
ExprVectorProcessor<Object[]> right,
|
||||||
int maxVectorSize
|
int maxVectorSize,
|
||||||
|
ExpressionType inputType
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
super(
|
super(
|
||||||
CastToTypeVectorProcessor.cast(left, ExpressionType.STRING),
|
CastToTypeVectorProcessor.cast(left, inputType),
|
||||||
CastToTypeVectorProcessor.cast(right, ExpressionType.STRING),
|
CastToTypeVectorProcessor.cast(right, inputType),
|
||||||
maxVectorSize,
|
maxVectorSize,
|
||||||
new long[maxVectorSize]
|
new long[maxVectorSize]
|
||||||
);
|
);
|
||||||
|
@ -43,12 +45,12 @@ public abstract class LongOutStringsInFunctionVectorProcessor extends BivariateF
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
abstract Long processValue(@Nullable String leftVal, @Nullable String rightVal);
|
abstract Long processValue(@Nullable Object leftVal, @Nullable Object rightVal);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void processIndex(String[] strings, String[] strings2, int i)
|
void processIndex(Object[] in1, Object[] in2, int i)
|
||||||
{
|
{
|
||||||
final Long outVal = processValue(strings[i], strings2[i]);
|
final Long outVal = processValue(in1[i], in2[i]);
|
||||||
if (outVal == null) {
|
if (outVal == null) {
|
||||||
outValues[i] = 0L;
|
outValues[i] = 0L;
|
||||||
outNulls[i] = true;
|
outNulls[i] = true;
|
|
@ -19,41 +19,43 @@
|
||||||
|
|
||||||
package org.apache.druid.math.expr.vector;
|
package org.apache.druid.math.expr.vector;
|
||||||
|
|
||||||
import org.apache.druid.common.config.NullHandling;
|
|
||||||
import org.apache.druid.math.expr.Expr;
|
import org.apache.druid.math.expr.Expr;
|
||||||
import org.apache.druid.math.expr.ExpressionType;
|
import org.apache.druid.math.expr.ExpressionType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* many strings enter, one string leaves...
|
* many strings enter, one string leaves...
|
||||||
*/
|
*/
|
||||||
public abstract class StringOutMultiStringInVectorProcessor implements ExprVectorProcessor<String[]>
|
public abstract class ObjectOutMultiObjectInVectorProcessor implements ExprVectorProcessor<Object[]>
|
||||||
{
|
{
|
||||||
final ExprVectorProcessor<String[]>[] inputs;
|
final ExprVectorProcessor<Object[]>[] inputs;
|
||||||
final int maxVectorSize;
|
final int maxVectorSize;
|
||||||
final String[] outValues;
|
final Object[] outValues;
|
||||||
final boolean sqlCompatible = NullHandling.sqlCompatible();
|
|
||||||
|
|
||||||
protected StringOutMultiStringInVectorProcessor(
|
final ExpressionType expressionType;
|
||||||
ExprVectorProcessor<String[]>[] inputs,
|
|
||||||
int maxVectorSize
|
protected ObjectOutMultiObjectInVectorProcessor(
|
||||||
|
ExprVectorProcessor<Object[]>[] inputs,
|
||||||
|
int maxVectorSize,
|
||||||
|
ExpressionType objectType
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
this.inputs = inputs;
|
this.inputs = inputs;
|
||||||
this.maxVectorSize = maxVectorSize;
|
this.maxVectorSize = maxVectorSize;
|
||||||
this.outValues = new String[maxVectorSize];
|
this.outValues = new Object[maxVectorSize];
|
||||||
|
this.expressionType = objectType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ExpressionType getOutputType()
|
public ExpressionType getOutputType()
|
||||||
{
|
{
|
||||||
return ExpressionType.STRING;
|
return expressionType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ExprEvalVector<String[]> evalVector(Expr.VectorInputBinding bindings)
|
public ExprEvalVector<Object[]> evalVector(Expr.VectorInputBinding bindings)
|
||||||
{
|
{
|
||||||
final int currentSize = bindings.getCurrentVectorSize();
|
final int currentSize = bindings.getCurrentVectorSize();
|
||||||
final String[][] in = new String[inputs.length][];
|
final Object[][] in = new Object[inputs.length][];
|
||||||
for (int i = 0; i < inputs.length; i++) {
|
for (int i = 0; i < inputs.length; i++) {
|
||||||
in[i] = inputs[i].evalVector(bindings).values();
|
in[i] = inputs[i].evalVector(bindings).values();
|
||||||
}
|
}
|
||||||
|
@ -61,8 +63,8 @@ public abstract class StringOutMultiStringInVectorProcessor implements ExprVecto
|
||||||
for (int i = 0; i < currentSize; i++) {
|
for (int i = 0; i < currentSize; i++) {
|
||||||
processIndex(in, i);
|
processIndex(in, i);
|
||||||
}
|
}
|
||||||
return new ExprEvalStringVector(outValues);
|
return new ExprEvalObjectVector(outValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract void processIndex(String[][] in, int i);
|
abstract void processIndex(Object[][] in, int i);
|
||||||
}
|
}
|
|
@ -23,30 +23,34 @@ import org.apache.druid.math.expr.ExpressionType;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public abstract class StringOutStringsInFunctionVectorProcessor
|
public abstract class ObjectOutObjectsInFunctionVectorProcessor
|
||||||
extends BivariateFunctionVectorObjectProcessor<String[], String[], String[]>
|
extends BivariateFunctionVectorObjectProcessor<Object[], Object[], Object[]>
|
||||||
{
|
{
|
||||||
protected StringOutStringsInFunctionVectorProcessor(
|
final ExpressionType expressionType;
|
||||||
ExprVectorProcessor<String[]> left,
|
|
||||||
ExprVectorProcessor<String[]> right,
|
protected ObjectOutObjectsInFunctionVectorProcessor(
|
||||||
int maxVectorSize
|
ExprVectorProcessor<Object[]> left,
|
||||||
|
ExprVectorProcessor<Object[]> right,
|
||||||
|
int maxVectorSize,
|
||||||
|
ExpressionType expressionType
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
super(
|
super(
|
||||||
CastToTypeVectorProcessor.cast(left, ExpressionType.STRING),
|
CastToTypeVectorProcessor.cast(left, expressionType),
|
||||||
CastToTypeVectorProcessor.cast(right, ExpressionType.STRING),
|
CastToTypeVectorProcessor.cast(right, expressionType),
|
||||||
maxVectorSize,
|
maxVectorSize,
|
||||||
new String[maxVectorSize]
|
new Object[maxVectorSize]
|
||||||
);
|
);
|
||||||
|
this.expressionType = expressionType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
protected abstract String processValue(@Nullable String leftVal, @Nullable String rightVal);
|
protected abstract Object processValue(@Nullable Object leftVal, @Nullable Object rightVal);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void processIndex(String[] strings, String[] strings2, int i)
|
void processIndex(Object[] in1, Object[] in2, int i)
|
||||||
{
|
{
|
||||||
outValues[i] = processValue(strings[i], strings2[i]);
|
outValues[i] = processValue(in1[i], in2[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -56,14 +60,14 @@ public abstract class StringOutStringsInFunctionVectorProcessor
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
ExprEvalVector<String[]> asEval()
|
ExprEvalVector<Object[]> asEval()
|
||||||
{
|
{
|
||||||
return new ExprEvalStringVector(outValues);
|
return new ExprEvalObjectVector(outValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ExpressionType getOutputType()
|
public ExpressionType getOutputType()
|
||||||
{
|
{
|
||||||
return ExpressionType.STRING;
|
return expressionType;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -38,7 +38,7 @@ public class VectorComparisonProcessors
|
||||||
Expr.VectorInputBindingInspector inspector,
|
Expr.VectorInputBindingInspector inspector,
|
||||||
Expr left,
|
Expr left,
|
||||||
Expr right,
|
Expr right,
|
||||||
Supplier<LongOutStringsInFunctionVectorProcessor> longOutStringsInFunctionVectorProcessor,
|
Supplier<LongOutObjectsInFunctionVectorProcessor> longOutStringsInFunctionVectorProcessor,
|
||||||
Supplier<LongOutLongsInFunctionVectorValueProcessor> longOutLongsInProcessor,
|
Supplier<LongOutLongsInFunctionVectorValueProcessor> longOutLongsInProcessor,
|
||||||
Supplier<DoubleOutLongDoubleInFunctionVectorValueProcessor> doubleOutLongDoubleInProcessor,
|
Supplier<DoubleOutLongDoubleInFunctionVectorValueProcessor> doubleOutLongDoubleInProcessor,
|
||||||
Supplier<DoubleOutDoubleLongInFunctionVectorValueProcessor> doubleOutDoubleLongInProcessor,
|
Supplier<DoubleOutDoubleLongInFunctionVectorValueProcessor> doubleOutDoubleLongInProcessor,
|
||||||
|
@ -81,7 +81,7 @@ public class VectorComparisonProcessors
|
||||||
Expr.VectorInputBindingInspector inspector,
|
Expr.VectorInputBindingInspector inspector,
|
||||||
Expr left,
|
Expr left,
|
||||||
Expr right,
|
Expr right,
|
||||||
Supplier<LongOutStringsInFunctionVectorProcessor> longOutStringsInFunctionVectorProcessor,
|
Supplier<LongOutObjectsInFunctionVectorProcessor> longOutStringsInFunctionVectorProcessor,
|
||||||
Supplier<LongOutLongsInFunctionVectorValueProcessor> longOutLongsInProcessor,
|
Supplier<LongOutLongsInFunctionVectorValueProcessor> longOutLongsInProcessor,
|
||||||
Supplier<LongOutLongDoubleInFunctionVectorValueProcessor> longOutLongDoubleInProcessor,
|
Supplier<LongOutLongDoubleInFunctionVectorValueProcessor> longOutLongDoubleInProcessor,
|
||||||
Supplier<LongOutDoubleLongInFunctionVectorValueProcessor> longOutDoubleLongInProcessor,
|
Supplier<LongOutDoubleLongInFunctionVectorValueProcessor> longOutDoubleLongInProcessor,
|
||||||
|
@ -136,15 +136,16 @@ public class VectorComparisonProcessors
|
||||||
inspector,
|
inspector,
|
||||||
left,
|
left,
|
||||||
right,
|
right,
|
||||||
() -> new LongOutStringsInFunctionVectorProcessor(
|
() -> new LongOutObjectsInFunctionVectorProcessor(
|
||||||
left.buildVectorized(inspector),
|
left.buildVectorized(inspector),
|
||||||
right.buildVectorized(inspector),
|
right.buildVectorized(inspector),
|
||||||
inspector.getMaxVectorSize()
|
inspector.getMaxVectorSize(),
|
||||||
|
ExpressionType.STRING
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
Long processValue(@Nullable String leftVal, @Nullable String rightVal)
|
Long processValue(@Nullable Object leftVal, @Nullable Object rightVal)
|
||||||
{
|
{
|
||||||
return Evals.asLong(Objects.equals(leftVal, rightVal));
|
return Evals.asLong(Objects.equals(leftVal, rightVal));
|
||||||
}
|
}
|
||||||
|
@ -203,15 +204,16 @@ public class VectorComparisonProcessors
|
||||||
inspector,
|
inspector,
|
||||||
left,
|
left,
|
||||||
right,
|
right,
|
||||||
() -> new LongOutStringsInFunctionVectorProcessor(
|
() -> new LongOutObjectsInFunctionVectorProcessor(
|
||||||
left.buildVectorized(inspector),
|
left.buildVectorized(inspector),
|
||||||
right.buildVectorized(inspector),
|
right.buildVectorized(inspector),
|
||||||
inspector.getMaxVectorSize()
|
inspector.getMaxVectorSize(),
|
||||||
|
ExpressionType.STRING
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
Long processValue(@Nullable String leftVal, @Nullable String rightVal)
|
Long processValue(@Nullable Object leftVal, @Nullable Object rightVal)
|
||||||
{
|
{
|
||||||
return Evals.asLong(Objects.equals(leftVal, rightVal));
|
return Evals.asLong(Objects.equals(leftVal, rightVal));
|
||||||
}
|
}
|
||||||
|
@ -278,15 +280,16 @@ public class VectorComparisonProcessors
|
||||||
inspector,
|
inspector,
|
||||||
left,
|
left,
|
||||||
right,
|
right,
|
||||||
() -> new LongOutStringsInFunctionVectorProcessor(
|
() -> new LongOutObjectsInFunctionVectorProcessor(
|
||||||
left.buildVectorized(inspector),
|
left.buildVectorized(inspector),
|
||||||
right.buildVectorized(inspector),
|
right.buildVectorized(inspector),
|
||||||
inspector.getMaxVectorSize()
|
inspector.getMaxVectorSize(),
|
||||||
|
ExpressionType.STRING
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
Long processValue(@Nullable String leftVal, @Nullable String rightVal)
|
Long processValue(@Nullable Object leftVal, @Nullable Object rightVal)
|
||||||
{
|
{
|
||||||
return Evals.asLong(!Objects.equals(leftVal, rightVal));
|
return Evals.asLong(!Objects.equals(leftVal, rightVal));
|
||||||
}
|
}
|
||||||
|
@ -345,15 +348,16 @@ public class VectorComparisonProcessors
|
||||||
inspector,
|
inspector,
|
||||||
left,
|
left,
|
||||||
right,
|
right,
|
||||||
() -> new LongOutStringsInFunctionVectorProcessor(
|
() -> new LongOutObjectsInFunctionVectorProcessor(
|
||||||
left.buildVectorized(inspector),
|
left.buildVectorized(inspector),
|
||||||
right.buildVectorized(inspector),
|
right.buildVectorized(inspector),
|
||||||
inspector.getMaxVectorSize()
|
inspector.getMaxVectorSize(),
|
||||||
|
ExpressionType.STRING
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
Long processValue(@Nullable String leftVal, @Nullable String rightVal)
|
Long processValue(@Nullable Object leftVal, @Nullable Object rightVal)
|
||||||
{
|
{
|
||||||
return Evals.asLong(!Objects.equals(leftVal, rightVal));
|
return Evals.asLong(!Objects.equals(leftVal, rightVal));
|
||||||
}
|
}
|
||||||
|
@ -420,17 +424,20 @@ public class VectorComparisonProcessors
|
||||||
inspector,
|
inspector,
|
||||||
left,
|
left,
|
||||||
right,
|
right,
|
||||||
() -> new LongOutStringsInFunctionVectorProcessor(
|
() -> new LongOutObjectsInFunctionVectorProcessor(
|
||||||
left.buildVectorized(inspector),
|
left.buildVectorized(inspector),
|
||||||
right.buildVectorized(inspector),
|
right.buildVectorized(inspector),
|
||||||
inspector.getMaxVectorSize()
|
inspector.getMaxVectorSize(),
|
||||||
|
ExpressionType.STRING
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
Long processValue(@Nullable String leftVal, @Nullable String rightVal)
|
Long processValue(@Nullable Object leftVal, @Nullable Object rightVal)
|
||||||
{
|
{
|
||||||
return Evals.asLong(Comparators.<String>naturalNullsFirst().compare(leftVal, rightVal) >= 0);
|
return Evals.asLong(
|
||||||
|
Comparators.<String>naturalNullsFirst().compare((String) leftVal, (String) rightVal) >= 0
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
() -> new LongOutLongsInFunctionVectorValueProcessor(
|
() -> new LongOutLongsInFunctionVectorValueProcessor(
|
||||||
|
@ -487,17 +494,20 @@ public class VectorComparisonProcessors
|
||||||
inspector,
|
inspector,
|
||||||
left,
|
left,
|
||||||
right,
|
right,
|
||||||
() -> new LongOutStringsInFunctionVectorProcessor(
|
() -> new LongOutObjectsInFunctionVectorProcessor(
|
||||||
left.buildVectorized(inspector),
|
left.buildVectorized(inspector),
|
||||||
right.buildVectorized(inspector),
|
right.buildVectorized(inspector),
|
||||||
inspector.getMaxVectorSize()
|
inspector.getMaxVectorSize(),
|
||||||
|
ExpressionType.STRING
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
Long processValue(@Nullable String leftVal, @Nullable String rightVal)
|
Long processValue(@Nullable Object leftVal, @Nullable Object rightVal)
|
||||||
{
|
{
|
||||||
return Evals.asLong(Comparators.<String>naturalNullsFirst().compare(leftVal, rightVal) >= 0);
|
return Evals.asLong(
|
||||||
|
Comparators.<String>naturalNullsFirst().compare((String) leftVal, (String) rightVal) >= 0
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
() -> new LongOutLongsInFunctionVectorValueProcessor(
|
() -> new LongOutLongsInFunctionVectorValueProcessor(
|
||||||
|
@ -562,17 +572,20 @@ public class VectorComparisonProcessors
|
||||||
inspector,
|
inspector,
|
||||||
left,
|
left,
|
||||||
right,
|
right,
|
||||||
() -> new LongOutStringsInFunctionVectorProcessor(
|
() -> new LongOutObjectsInFunctionVectorProcessor(
|
||||||
left.buildVectorized(inspector),
|
left.buildVectorized(inspector),
|
||||||
right.buildVectorized(inspector),
|
right.buildVectorized(inspector),
|
||||||
inspector.getMaxVectorSize()
|
inspector.getMaxVectorSize(),
|
||||||
|
ExpressionType.STRING
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
Long processValue(@Nullable String leftVal, @Nullable String rightVal)
|
Long processValue(@Nullable Object leftVal, @Nullable Object rightVal)
|
||||||
{
|
{
|
||||||
return Evals.asLong(Comparators.<String>naturalNullsFirst().compare(leftVal, rightVal) > 0);
|
return Evals.asLong(
|
||||||
|
Comparators.<String>naturalNullsFirst().compare((String) leftVal, (String) rightVal) > 0
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
() -> new LongOutLongsInFunctionVectorValueProcessor(
|
() -> new LongOutLongsInFunctionVectorValueProcessor(
|
||||||
|
@ -629,17 +642,20 @@ public class VectorComparisonProcessors
|
||||||
inspector,
|
inspector,
|
||||||
left,
|
left,
|
||||||
right,
|
right,
|
||||||
() -> new LongOutStringsInFunctionVectorProcessor(
|
() -> new LongOutObjectsInFunctionVectorProcessor(
|
||||||
left.buildVectorized(inspector),
|
left.buildVectorized(inspector),
|
||||||
right.buildVectorized(inspector),
|
right.buildVectorized(inspector),
|
||||||
inspector.getMaxVectorSize()
|
inspector.getMaxVectorSize(),
|
||||||
|
ExpressionType.STRING
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
Long processValue(@Nullable String leftVal, @Nullable String rightVal)
|
Long processValue(@Nullable Object leftVal, @Nullable Object rightVal)
|
||||||
{
|
{
|
||||||
return Evals.asLong(Comparators.<String>naturalNullsFirst().compare(leftVal, rightVal) > 0);
|
return Evals.asLong(
|
||||||
|
Comparators.<String>naturalNullsFirst().compare((String) leftVal, (String) rightVal) > 0
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
() -> new LongOutLongsInFunctionVectorValueProcessor(
|
() -> new LongOutLongsInFunctionVectorValueProcessor(
|
||||||
|
@ -704,17 +720,20 @@ public class VectorComparisonProcessors
|
||||||
inspector,
|
inspector,
|
||||||
left,
|
left,
|
||||||
right,
|
right,
|
||||||
() -> new LongOutStringsInFunctionVectorProcessor(
|
() -> new LongOutObjectsInFunctionVectorProcessor(
|
||||||
left.buildVectorized(inspector),
|
left.buildVectorized(inspector),
|
||||||
right.buildVectorized(inspector),
|
right.buildVectorized(inspector),
|
||||||
inspector.getMaxVectorSize()
|
inspector.getMaxVectorSize(),
|
||||||
|
ExpressionType.STRING
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
Long processValue(@Nullable String leftVal, @Nullable String rightVal)
|
Long processValue(@Nullable Object leftVal, @Nullable Object rightVal)
|
||||||
{
|
{
|
||||||
return Evals.asLong(Comparators.<String>naturalNullsFirst().compare(leftVal, rightVal) <= 0);
|
return Evals.asLong(
|
||||||
|
Comparators.<String>naturalNullsFirst().compare((String) leftVal, (String) rightVal) <= 0
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
() -> new LongOutLongsInFunctionVectorValueProcessor(
|
() -> new LongOutLongsInFunctionVectorValueProcessor(
|
||||||
|
@ -771,17 +790,20 @@ public class VectorComparisonProcessors
|
||||||
inspector,
|
inspector,
|
||||||
left,
|
left,
|
||||||
right,
|
right,
|
||||||
() -> new LongOutStringsInFunctionVectorProcessor(
|
() -> new LongOutObjectsInFunctionVectorProcessor(
|
||||||
left.buildVectorized(inspector),
|
left.buildVectorized(inspector),
|
||||||
right.buildVectorized(inspector),
|
right.buildVectorized(inspector),
|
||||||
inspector.getMaxVectorSize()
|
inspector.getMaxVectorSize(),
|
||||||
|
ExpressionType.STRING
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
Long processValue(@Nullable String leftVal, @Nullable String rightVal)
|
Long processValue(@Nullable Object leftVal, @Nullable Object rightVal)
|
||||||
{
|
{
|
||||||
return Evals.asLong(Comparators.<String>naturalNullsFirst().compare(leftVal, rightVal) <= 0);
|
return Evals.asLong(
|
||||||
|
Comparators.<String>naturalNullsFirst().compare((String) leftVal, (String) rightVal) <= 0
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
() -> new LongOutLongsInFunctionVectorValueProcessor(
|
() -> new LongOutLongsInFunctionVectorValueProcessor(
|
||||||
|
@ -846,17 +868,20 @@ public class VectorComparisonProcessors
|
||||||
inspector,
|
inspector,
|
||||||
left,
|
left,
|
||||||
right,
|
right,
|
||||||
() -> new LongOutStringsInFunctionVectorProcessor(
|
() -> new LongOutObjectsInFunctionVectorProcessor(
|
||||||
left.buildVectorized(inspector),
|
left.buildVectorized(inspector),
|
||||||
right.buildVectorized(inspector),
|
right.buildVectorized(inspector),
|
||||||
inspector.getMaxVectorSize()
|
inspector.getMaxVectorSize(),
|
||||||
|
ExpressionType.STRING
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
Long processValue(@Nullable String leftVal, @Nullable String rightVal)
|
Long processValue(@Nullable Object leftVal, @Nullable Object rightVal)
|
||||||
{
|
{
|
||||||
return Evals.asLong(Comparators.<String>naturalNullsFirst().compare(leftVal, rightVal) < 0);
|
return Evals.asLong(
|
||||||
|
Comparators.<String>naturalNullsFirst().compare((String) leftVal, (String) rightVal) < 0
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
() -> new LongOutLongsInFunctionVectorValueProcessor(
|
() -> new LongOutLongsInFunctionVectorValueProcessor(
|
||||||
|
@ -913,17 +938,20 @@ public class VectorComparisonProcessors
|
||||||
inspector,
|
inspector,
|
||||||
left,
|
left,
|
||||||
right,
|
right,
|
||||||
() -> new LongOutStringsInFunctionVectorProcessor(
|
() -> new LongOutObjectsInFunctionVectorProcessor(
|
||||||
left.buildVectorized(inspector),
|
left.buildVectorized(inspector),
|
||||||
right.buildVectorized(inspector),
|
right.buildVectorized(inspector),
|
||||||
inspector.getMaxVectorSize()
|
inspector.getMaxVectorSize(),
|
||||||
|
ExpressionType.STRING
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
Long processValue(@Nullable String leftVal, @Nullable String rightVal)
|
Long processValue(@Nullable Object leftVal, @Nullable Object rightVal)
|
||||||
{
|
{
|
||||||
return Evals.asLong(Comparators.<String>naturalNullsFirst().compare(leftVal, rightVal) < 0);
|
return Evals.asLong(
|
||||||
|
Comparators.<String>naturalNullsFirst().compare((String) leftVal, (String) rightVal) < 0
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
() -> new LongOutLongsInFunctionVectorValueProcessor(
|
() -> new LongOutLongsInFunctionVectorValueProcessor(
|
||||||
|
|
|
@ -82,9 +82,9 @@ public class VectorProcessors
|
||||||
|
|
||||||
public static <T> ExprVectorProcessor<T> constant(@Nullable String constant, int maxVectorSize)
|
public static <T> ExprVectorProcessor<T> constant(@Nullable String constant, int maxVectorSize)
|
||||||
{
|
{
|
||||||
final String[] strings = new String[maxVectorSize];
|
final Object[] strings = new Object[maxVectorSize];
|
||||||
Arrays.fill(strings, constant);
|
Arrays.fill(strings, constant);
|
||||||
final ExprEvalStringVector eval = new ExprEvalStringVector(strings);
|
final ExprEvalObjectVector eval = new ExprEvalObjectVector(strings);
|
||||||
return new ExprVectorProcessor<T>()
|
return new ExprVectorProcessor<T>()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
|
@ -159,23 +159,29 @@ public class VectorProcessors
|
||||||
|
|
||||||
public static <T> ExprVectorProcessor<T> parseLong(Expr.VectorInputBindingInspector inspector, Expr arg, int radix)
|
public static <T> ExprVectorProcessor<T> parseLong(Expr.VectorInputBindingInspector inspector, Expr arg, int radix)
|
||||||
{
|
{
|
||||||
final ExprVectorProcessor<?> processor = new LongOutStringInFunctionVectorProcessor(
|
final ExprVectorProcessor<?> processor = new LongOutObjectInFunctionVectorProcessor(
|
||||||
CastToTypeVectorProcessor.cast(arg.buildVectorized(inspector), ExpressionType.STRING),
|
arg.buildVectorized(inspector),
|
||||||
inspector.getMaxVectorSize()
|
inspector.getMaxVectorSize(),
|
||||||
|
ExpressionType.STRING
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public void processIndex(String[] strings, long[] longs, boolean[] outputNulls, int i)
|
public void processIndex(Object[] strings, long[] longs, boolean[] outputNulls, int i)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
final String input = strings[i];
|
final String input = (String) strings[i];
|
||||||
if (radix == 16 && (input.startsWith("0x") || input.startsWith("0X"))) {
|
if (input == null) {
|
||||||
// Strip leading 0x from hex strings.
|
longs[i] = 0L;
|
||||||
longs[i] = Long.parseLong(input.substring(2), radix);
|
outputNulls[i] = NullHandling.sqlCompatible();
|
||||||
} else {
|
} else {
|
||||||
longs[i] = Long.parseLong(input, radix);
|
if (radix == 16 && (input.startsWith("0x") || input.startsWith("0X"))) {
|
||||||
|
// Strip leading 0x from hex strings.
|
||||||
|
longs[i] = Long.parseLong(input.substring(2), radix);
|
||||||
|
} else {
|
||||||
|
longs[i] = Long.parseLong(input, radix);
|
||||||
|
}
|
||||||
|
outputNulls[i] = false;
|
||||||
}
|
}
|
||||||
outputNulls[i] = false;
|
|
||||||
}
|
}
|
||||||
catch (NumberFormatException e) {
|
catch (NumberFormatException e) {
|
||||||
longs[i] = 0L;
|
longs[i] = 0L;
|
||||||
|
@ -199,16 +205,16 @@ public class VectorProcessors
|
||||||
|
|
||||||
ExprVectorProcessor<?> processor = null;
|
ExprVectorProcessor<?> processor = null;
|
||||||
if (Types.is(type, ExprType.STRING)) {
|
if (Types.is(type, ExprType.STRING)) {
|
||||||
final ExprVectorProcessor<String[]> input = expr.buildVectorized(inspector);
|
final ExprVectorProcessor<Object[]> input = expr.buildVectorized(inspector);
|
||||||
processor = new ExprVectorProcessor<long[]>()
|
processor = new ExprVectorProcessor<long[]>()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public ExprEvalVector<long[]> evalVector(Expr.VectorInputBinding bindings)
|
public ExprEvalVector<long[]> evalVector(Expr.VectorInputBinding bindings)
|
||||||
{
|
{
|
||||||
final ExprEvalVector<String[]> inputEval = input.evalVector(bindings);
|
final ExprEvalVector<Object[]> inputEval = input.evalVector(bindings);
|
||||||
|
|
||||||
final int currentSize = bindings.getCurrentVectorSize();
|
final int currentSize = bindings.getCurrentVectorSize();
|
||||||
final String[] values = inputEval.values();
|
final Object[] values = inputEval.values();
|
||||||
for (int i = 0; i < currentSize; i++) {
|
for (int i = 0; i < currentSize; i++) {
|
||||||
if (values[i] == null) {
|
if (values[i] == null) {
|
||||||
outputValues[i] = 1L;
|
outputValues[i] = 1L;
|
||||||
|
@ -307,16 +313,16 @@ public class VectorProcessors
|
||||||
|
|
||||||
ExprVectorProcessor<?> processor = null;
|
ExprVectorProcessor<?> processor = null;
|
||||||
if (Types.is(type, ExprType.STRING)) {
|
if (Types.is(type, ExprType.STRING)) {
|
||||||
final ExprVectorProcessor<String[]> input = expr.buildVectorized(inspector);
|
final ExprVectorProcessor<Object[]> input = expr.buildVectorized(inspector);
|
||||||
processor = new ExprVectorProcessor<long[]>()
|
processor = new ExprVectorProcessor<long[]>()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public ExprEvalVector<long[]> evalVector(Expr.VectorInputBinding bindings)
|
public ExprEvalVector<long[]> evalVector(Expr.VectorInputBinding bindings)
|
||||||
{
|
{
|
||||||
final ExprEvalVector<String[]> inputEval = input.evalVector(bindings);
|
final ExprEvalVector<Object[]> inputEval = input.evalVector(bindings);
|
||||||
|
|
||||||
final int currentSize = bindings.getCurrentVectorSize();
|
final int currentSize = bindings.getCurrentVectorSize();
|
||||||
final String[] values = inputEval.values();
|
final Object[] values = inputEval.values();
|
||||||
for (int i = 0; i < currentSize; i++) {
|
for (int i = 0; i < currentSize; i++) {
|
||||||
if (values[i] == null) {
|
if (values[i] == null) {
|
||||||
outputValues[i] = 0L;
|
outputValues[i] = 0L;
|
||||||
|
@ -483,19 +489,19 @@ public class VectorProcessors
|
||||||
return new ExprEvalDoubleVector(output, outputNulls);
|
return new ExprEvalDoubleVector(output, outputNulls);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
() -> new SymmetricalBivariateFunctionVectorProcessor<String[]>(
|
() -> new SymmetricalBivariateFunctionVectorProcessor<Object[]>(
|
||||||
ExpressionType.STRING,
|
ExpressionType.STRING,
|
||||||
left.buildVectorized(inspector),
|
left.buildVectorized(inspector),
|
||||||
right.buildVectorized(inspector)
|
right.buildVectorized(inspector)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
final String[] output = new String[maxVectorSize];
|
final Object[] output = new Object[maxVectorSize];
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void processIndex(
|
public void processIndex(
|
||||||
String[] leftInput,
|
Object[] leftInput,
|
||||||
@Nullable boolean[] leftNulls,
|
@Nullable boolean[] leftNulls,
|
||||||
String[] rightInput,
|
Object[] rightInput,
|
||||||
@Nullable boolean[] rightNulls,
|
@Nullable boolean[] rightNulls,
|
||||||
int i
|
int i
|
||||||
)
|
)
|
||||||
|
@ -504,9 +510,9 @@ public class VectorProcessors
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ExprEvalVector<String[]> asEval()
|
public ExprEvalVector<Object[]> asEval()
|
||||||
{
|
{
|
||||||
return new ExprEvalStringVector(output);
|
return new ExprEvalObjectVector(output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -518,14 +524,18 @@ public class VectorProcessors
|
||||||
final int maxVectorSize = inspector.getMaxVectorSize();
|
final int maxVectorSize = inspector.getMaxVectorSize();
|
||||||
ExprVectorProcessor<?> processor = null;
|
ExprVectorProcessor<?> processor = null;
|
||||||
if (Types.is(inputType, ExprType.STRING)) {
|
if (Types.is(inputType, ExprType.STRING)) {
|
||||||
processor = new LongOutStringInFunctionVectorProcessor(expr.buildVectorized(inspector), maxVectorSize)
|
processor = new LongOutObjectInFunctionVectorProcessor(
|
||||||
|
expr.buildVectorized(inspector),
|
||||||
|
maxVectorSize,
|
||||||
|
ExpressionType.STRING
|
||||||
|
)
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public void processIndex(String[] strings, long[] longs, boolean[] outputNulls, int i)
|
public void processIndex(Object[] strings, long[] longs, boolean[] outputNulls, int i)
|
||||||
{
|
{
|
||||||
outputNulls[i] = strings[i] == null;
|
outputNulls[i] = strings[i] == null;
|
||||||
if (!outputNulls[i]) {
|
if (!outputNulls[i]) {
|
||||||
longs[i] = Evals.asLong(!Evals.asBoolean(strings[i]));
|
longs[i] = Evals.asLong(!Evals.asBoolean((String) strings[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -670,7 +680,7 @@ public class VectorProcessors
|
||||||
return new ExprEvalLongVector(output, outputNulls);
|
return new ExprEvalLongVector(output, outputNulls);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
() -> new BivariateFunctionVectorProcessor<String[], String[], long[]>(
|
() -> new BivariateFunctionVectorProcessor<Object[], Object[], long[]>(
|
||||||
ExpressionType.LONG,
|
ExpressionType.LONG,
|
||||||
left.buildVectorized(inspector),
|
left.buildVectorized(inspector),
|
||||||
right.buildVectorized(inspector)
|
right.buildVectorized(inspector)
|
||||||
|
@ -681,9 +691,9 @@ public class VectorProcessors
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void processIndex(
|
public void processIndex(
|
||||||
String[] leftInput,
|
Object[] leftInput,
|
||||||
@Nullable boolean[] leftNulls,
|
@Nullable boolean[] leftNulls,
|
||||||
String[] rightInput,
|
Object[] rightInput,
|
||||||
@Nullable boolean[] rightNulls,
|
@Nullable boolean[] rightNulls,
|
||||||
int i
|
int i
|
||||||
)
|
)
|
||||||
|
@ -697,17 +707,17 @@ public class VectorProcessors
|
||||||
outputNulls[i] = true;
|
outputNulls[i] = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final boolean bool = Evals.asBoolean(rightInput[i]);
|
final boolean bool = Evals.asBoolean((String) rightInput[i]);
|
||||||
output[i] = Evals.asLong(bool);
|
output[i] = Evals.asLong(bool);
|
||||||
outputNulls[i] = !bool;
|
outputNulls[i] = !bool;
|
||||||
return;
|
return;
|
||||||
} else if (rightNull) {
|
} else if (rightNull) {
|
||||||
final boolean bool = Evals.asBoolean(leftInput[i]);
|
final boolean bool = Evals.asBoolean((String) leftInput[i]);
|
||||||
output[i] = Evals.asLong(bool);
|
output[i] = Evals.asLong(bool);
|
||||||
outputNulls[i] = !bool;
|
outputNulls[i] = !bool;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
output[i] = Evals.asLong(Evals.asBoolean(leftInput[i]) || Evals.asBoolean(rightInput[i]));
|
output[i] = Evals.asLong(Evals.asBoolean((String) leftInput[i]) || Evals.asBoolean((String) rightInput[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -824,7 +834,7 @@ public class VectorProcessors
|
||||||
return new ExprEvalLongVector(output, outputNulls);
|
return new ExprEvalLongVector(output, outputNulls);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
() -> new BivariateFunctionVectorProcessor<String[], String[], long[]>(
|
() -> new BivariateFunctionVectorProcessor<Object[], Object[], long[]>(
|
||||||
ExpressionType.STRING,
|
ExpressionType.STRING,
|
||||||
left.buildVectorized(inputTypes),
|
left.buildVectorized(inputTypes),
|
||||||
right.buildVectorized(inputTypes)
|
right.buildVectorized(inputTypes)
|
||||||
|
@ -835,9 +845,9 @@ public class VectorProcessors
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void processIndex(
|
public void processIndex(
|
||||||
String[] leftInput,
|
Object[] leftInput,
|
||||||
@Nullable boolean[] leftNulls,
|
@Nullable boolean[] leftNulls,
|
||||||
String[] rightInput,
|
Object[] rightInput,
|
||||||
@Nullable boolean[] rightNulls,
|
@Nullable boolean[] rightNulls,
|
||||||
int i
|
int i
|
||||||
)
|
)
|
||||||
|
@ -851,17 +861,19 @@ public class VectorProcessors
|
||||||
outputNulls[i] = true;
|
outputNulls[i] = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final boolean bool = Evals.asBoolean(rightInput[i]);
|
final boolean bool = Evals.asBoolean((String) rightInput[i]);
|
||||||
output[i] = Evals.asLong(bool);
|
output[i] = Evals.asLong(bool);
|
||||||
outputNulls[i] = bool;
|
outputNulls[i] = bool;
|
||||||
return;
|
return;
|
||||||
} else if (rightNull) {
|
} else if (rightNull) {
|
||||||
final boolean bool = Evals.asBoolean(leftInput[i]);
|
final boolean bool = Evals.asBoolean((String) leftInput[i]);
|
||||||
output[i] = Evals.asLong(bool);
|
output[i] = Evals.asLong(bool);
|
||||||
outputNulls[i] = bool;
|
outputNulls[i] = bool;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
output[i] = Evals.asLong(Evals.asBoolean(leftInput[i]) && Evals.asBoolean(rightInput[i]));
|
output[i] = Evals.asLong(
|
||||||
|
Evals.asBoolean((String) leftInput[i]) && Evals.asBoolean((String) rightInput[i])
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
package org.apache.druid.math.expr.vector;
|
package org.apache.druid.math.expr.vector;
|
||||||
|
|
||||||
import org.apache.druid.common.config.NullHandling;
|
import org.apache.druid.common.config.NullHandling;
|
||||||
|
import org.apache.druid.math.expr.Evals;
|
||||||
import org.apache.druid.math.expr.Expr;
|
import org.apache.druid.math.expr.Expr;
|
||||||
import org.apache.druid.math.expr.ExpressionType;
|
import org.apache.druid.math.expr.ExpressionType;
|
||||||
|
|
||||||
|
@ -32,32 +33,35 @@ public class VectorStringProcessors
|
||||||
{
|
{
|
||||||
final ExprVectorProcessor processor;
|
final ExprVectorProcessor processor;
|
||||||
if (NullHandling.sqlCompatible()) {
|
if (NullHandling.sqlCompatible()) {
|
||||||
processor = new StringOutStringsInFunctionVectorProcessor(
|
processor = new ObjectOutObjectsInFunctionVectorProcessor(
|
||||||
left.buildVectorized(inspector),
|
left.buildVectorized(inspector),
|
||||||
right.buildVectorized(inspector),
|
right.buildVectorized(inspector),
|
||||||
inspector.getMaxVectorSize()
|
inspector.getMaxVectorSize(),
|
||||||
|
ExpressionType.STRING
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
protected String processValue(@Nullable String leftVal, @Nullable String rightVal)
|
protected String processValue(@Nullable Object leftVal, @Nullable Object rightVal)
|
||||||
{
|
{
|
||||||
// in sql compatible mode, nulls are handled by super class and never make it here...
|
// in sql compatible mode, nulls are handled by super class and never make it here...
|
||||||
return leftVal + rightVal;
|
return leftVal + (String) rightVal;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
processor = new StringOutStringsInFunctionVectorProcessor(
|
processor = new ObjectOutObjectsInFunctionVectorProcessor(
|
||||||
left.buildVectorized(inspector),
|
left.buildVectorized(inspector),
|
||||||
right.buildVectorized(inspector),
|
right.buildVectorized(inspector),
|
||||||
inspector.getMaxVectorSize()
|
inspector.getMaxVectorSize(),
|
||||||
|
ExpressionType.STRING
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
protected String processValue(@Nullable String leftVal, @Nullable String rightVal)
|
protected Object processValue(@Nullable Object leftVal, @Nullable Object rightVal)
|
||||||
{
|
{
|
||||||
return NullHandling.nullToEmptyIfNeeded(leftVal) + NullHandling.nullToEmptyIfNeeded(rightVal);
|
return NullHandling.nullToEmptyIfNeeded((String) leftVal)
|
||||||
|
+ NullHandling.nullToEmptyIfNeeded((String) rightVal);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -66,28 +70,32 @@ public class VectorStringProcessors
|
||||||
|
|
||||||
public static <T> ExprVectorProcessor<T> concat(Expr.VectorInputBindingInspector inspector, List<Expr> inputs)
|
public static <T> ExprVectorProcessor<T> concat(Expr.VectorInputBindingInspector inspector, List<Expr> inputs)
|
||||||
{
|
{
|
||||||
final ExprVectorProcessor<String[]>[] inputProcessors = new ExprVectorProcessor[inputs.size()];
|
final ExprVectorProcessor<Object[]>[] inputProcessors = new ExprVectorProcessor[inputs.size()];
|
||||||
for (int i = 0; i < inputs.size(); i++) {
|
for (int i = 0; i < inputs.size(); i++) {
|
||||||
inputProcessors[i] = CastToTypeVectorProcessor.cast(inputs.get(i).buildVectorized(inspector), ExpressionType.STRING);
|
inputProcessors[i] = CastToTypeVectorProcessor.cast(
|
||||||
|
inputs.get(i).buildVectorized(inspector),
|
||||||
|
ExpressionType.STRING
|
||||||
|
);
|
||||||
}
|
}
|
||||||
final ExprVectorProcessor processor = new StringOutMultiStringInVectorProcessor(
|
final ExprVectorProcessor processor = new ObjectOutMultiObjectInVectorProcessor(
|
||||||
inputProcessors,
|
inputProcessors,
|
||||||
inspector.getMaxVectorSize()
|
inspector.getMaxVectorSize(),
|
||||||
|
ExpressionType.STRING
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
void processIndex(String[][] in, int i)
|
void processIndex(Object[][] in, int i)
|
||||||
{
|
{
|
||||||
// Result of concatenation is null if any of the Values is null.
|
// Result of concatenation is null if any of the Values is null.
|
||||||
// e.g. 'select CONCAT(null, "abc") as c;' will return null as per Standard SQL spec.
|
// e.g. 'select CONCAT(null, "abc") as c;' will return null as per Standard SQL spec.
|
||||||
String first = NullHandling.nullToEmptyIfNeeded(in[0][i]);
|
String first = NullHandling.nullToEmptyIfNeeded(Evals.asString(in[0][i]));
|
||||||
if (first == null) {
|
if (first == null) {
|
||||||
outValues[i] = null;
|
outValues[i] = null;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final StringBuilder builder = new StringBuilder(first);
|
final StringBuilder builder = new StringBuilder(first);
|
||||||
for (int inputNumber = 1; inputNumber < in.length; inputNumber++) {
|
for (int inputNumber = 1; inputNumber < in.length; inputNumber++) {
|
||||||
final String s = NullHandling.nullToEmptyIfNeeded(in[inputNumber][i]);
|
final String s = NullHandling.nullToEmptyIfNeeded(Evals.asString(in[inputNumber][i]));
|
||||||
if (s == null) {
|
if (s == null) {
|
||||||
outValues[i] = null;
|
outValues[i] = null;
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -561,7 +561,7 @@ public class StringDictionaryEncodedColumn implements DictionaryEncodedColumn<St
|
||||||
class DictionaryEncodedStringSingleValueVectorObjectSelector implements VectorObjectSelector
|
class DictionaryEncodedStringSingleValueVectorObjectSelector implements VectorObjectSelector
|
||||||
{
|
{
|
||||||
private final int[] vector = new int[offset.getMaxVectorSize()];
|
private final int[] vector = new int[offset.getMaxVectorSize()];
|
||||||
private final String[] strings = new String[offset.getMaxVectorSize()];
|
private final Object[] strings = new Object[offset.getMaxVectorSize()];
|
||||||
private int id = ReadableVectorInspector.NULL_ID;
|
private int id = ReadableVectorInspector.NULL_ID;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -69,9 +69,9 @@ public class ExpressionVectorInputBinding implements Expr.VectorInputBinding
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T[] getObjectVector(String name)
|
public Object[] getObjectVector(String name)
|
||||||
{
|
{
|
||||||
return (T[]) objects.getOrDefault(name, nilSelector).getObjectVector();
|
return objects.getOrDefault(name, nilSelector).getObjectVector();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
package org.apache.druid.segment.virtual;
|
package org.apache.druid.segment.virtual;
|
||||||
|
|
||||||
import org.apache.druid.java.util.common.ISE;
|
import org.apache.druid.java.util.common.ISE;
|
||||||
|
import org.apache.druid.math.expr.Evals;
|
||||||
import org.apache.druid.math.expr.Expr;
|
import org.apache.druid.math.expr.Expr;
|
||||||
import org.apache.druid.math.expr.ExpressionType;
|
import org.apache.druid.math.expr.ExpressionType;
|
||||||
import org.apache.druid.math.expr.vector.ExprVectorProcessor;
|
import org.apache.druid.math.expr.vector.ExprVectorProcessor;
|
||||||
|
@ -43,7 +44,7 @@ public class SingleStringInputDeferredEvaluationExpressionDimensionVectorSelecto
|
||||||
implements SingleValueDimensionVectorSelector
|
implements SingleValueDimensionVectorSelector
|
||||||
{
|
{
|
||||||
private final SingleValueDimensionVectorSelector selector;
|
private final SingleValueDimensionVectorSelector selector;
|
||||||
private final ExprVectorProcessor<String[]> stringProcessor;
|
private final ExprVectorProcessor<Object[]> stringProcessor;
|
||||||
private final StringLookupVectorInputBindings inputBinding;
|
private final StringLookupVectorInputBindings inputBinding;
|
||||||
|
|
||||||
public SingleStringInputDeferredEvaluationExpressionDimensionVectorSelector(
|
public SingleStringInputDeferredEvaluationExpressionDimensionVectorSelector(
|
||||||
|
@ -75,7 +76,7 @@ public class SingleStringInputDeferredEvaluationExpressionDimensionVectorSelecto
|
||||||
public String lookupName(int id)
|
public String lookupName(int id)
|
||||||
{
|
{
|
||||||
inputBinding.currentValue[0] = selector.lookupName(id);
|
inputBinding.currentValue[0] = selector.lookupName(id);
|
||||||
return stringProcessor.evalVector(inputBinding).values()[0];
|
return Evals.asString(stringProcessor.evalVector(inputBinding).values()[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -118,7 +119,7 @@ public class SingleStringInputDeferredEvaluationExpressionDimensionVectorSelecto
|
||||||
*/
|
*/
|
||||||
private static final class StringLookupVectorInputBindings implements Expr.VectorInputBinding
|
private static final class StringLookupVectorInputBindings implements Expr.VectorInputBinding
|
||||||
{
|
{
|
||||||
private final String[] currentValue = new String[1];
|
private final Object[] currentValue = new Object[1];
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -35,12 +35,14 @@ import org.apache.druid.query.aggregation.AggregationTestHelper;
|
||||||
import org.apache.druid.query.aggregation.CountAggregatorFactory;
|
import org.apache.druid.query.aggregation.CountAggregatorFactory;
|
||||||
import org.apache.druid.query.aggregation.LongSumAggregatorFactory;
|
import org.apache.druid.query.aggregation.LongSumAggregatorFactory;
|
||||||
import org.apache.druid.query.dimension.DefaultDimensionSpec;
|
import org.apache.druid.query.dimension.DefaultDimensionSpec;
|
||||||
|
import org.apache.druid.query.expression.TestExprMacroTable;
|
||||||
import org.apache.druid.query.filter.InDimFilter;
|
import org.apache.druid.query.filter.InDimFilter;
|
||||||
import org.apache.druid.query.groupby.strategy.GroupByStrategySelector;
|
import org.apache.druid.query.groupby.strategy.GroupByStrategySelector;
|
||||||
import org.apache.druid.segment.Segment;
|
import org.apache.druid.segment.Segment;
|
||||||
import org.apache.druid.segment.column.ColumnType;
|
import org.apache.druid.segment.column.ColumnType;
|
||||||
import org.apache.druid.segment.column.RowSignature;
|
import org.apache.druid.segment.column.RowSignature;
|
||||||
import org.apache.druid.segment.column.ValueType;
|
import org.apache.druid.segment.column.ValueType;
|
||||||
|
import org.apache.druid.segment.virtual.ExpressionVirtualColumn;
|
||||||
import org.apache.druid.segment.virtual.NestedFieldVirtualColumn;
|
import org.apache.druid.segment.virtual.NestedFieldVirtualColumn;
|
||||||
import org.apache.druid.testing.InitializedNullHandlingTest;
|
import org.apache.druid.testing.InitializedNullHandlingTest;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
|
@ -76,6 +78,8 @@ public class NestedDataGroupByQueryTest extends InitializedNullHandlingTest
|
||||||
private final TrinaryFn<AggregationTestHelper, TemporaryFolder, Closer, List<Segment>> segmentsGenerator;
|
private final TrinaryFn<AggregationTestHelper, TemporaryFolder, Closer, List<Segment>> segmentsGenerator;
|
||||||
private final String segmentsName;
|
private final String segmentsName;
|
||||||
|
|
||||||
|
private boolean cannotVectorize = false;
|
||||||
|
|
||||||
public NestedDataGroupByQueryTest(
|
public NestedDataGroupByQueryTest(
|
||||||
GroupByQueryConfig config,
|
GroupByQueryConfig config,
|
||||||
TrinaryFn<AggregationTestHelper, TemporaryFolder, Closer, List<Segment>> segmentGenerator,
|
TrinaryFn<AggregationTestHelper, TemporaryFolder, Closer, List<Segment>> segmentGenerator,
|
||||||
|
@ -273,6 +277,46 @@ public class NestedDataGroupByQueryTest extends InitializedNullHandlingTest
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGroupByNonExistentVirtualColumn()
|
||||||
|
{
|
||||||
|
if (GroupByStrategySelector.STRATEGY_V1.equals(config.getDefaultStrategy())) {
|
||||||
|
expectedException.expect(RuntimeException.class);
|
||||||
|
expectedException.expectMessage(
|
||||||
|
"GroupBy v1 does not support dimension selectors with unknown cardinality."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
GroupByQuery groupQuery = GroupByQuery.builder()
|
||||||
|
.setDataSource("test_datasource")
|
||||||
|
.setGranularity(Granularities.ALL)
|
||||||
|
.setInterval(Intervals.ETERNITY)
|
||||||
|
.setDimensions(DefaultDimensionSpec.of("v1"))
|
||||||
|
.setVirtualColumns(
|
||||||
|
new NestedFieldVirtualColumn("fake", "$.fake", "v0", ColumnType.STRING),
|
||||||
|
new ExpressionVirtualColumn(
|
||||||
|
"v1",
|
||||||
|
"concat(v0, 'foo')",
|
||||||
|
ColumnType.STRING,
|
||||||
|
TestExprMacroTable.INSTANCE
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.setAggregatorSpecs(new CountAggregatorFactory("count"))
|
||||||
|
.setContext(getContext())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
|
||||||
|
Sequence<ResultRow> seq = helper.runQueryOnSegmentsObjs(segmentsGenerator.apply(helper, tempFolder, closer), groupQuery);
|
||||||
|
|
||||||
|
List<ResultRow> results = seq.toList();
|
||||||
|
verifyResults(
|
||||||
|
groupQuery.getResultRowSignature(),
|
||||||
|
results,
|
||||||
|
NullHandling.sqlCompatible()
|
||||||
|
? ImmutableList.of(new Object[]{null, 16L})
|
||||||
|
: ImmutableList.of(new Object[]{"foo", 16L})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
private static void verifyResults(RowSignature rowSignature, List<ResultRow> results, List<Object[]> expected)
|
private static void verifyResults(RowSignature rowSignature, List<ResultRow> results, List<Object[]> expected)
|
||||||
{
|
{
|
||||||
LOG.info("results:\n%s", results);
|
LOG.info("results:\n%s", results);
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
package org.apache.druid.segment.virtual;
|
package org.apache.druid.segment.virtual;
|
||||||
|
|
||||||
import org.apache.druid.math.expr.Expr;
|
import org.apache.druid.math.expr.Expr;
|
||||||
import org.apache.druid.math.expr.vector.ExprEvalStringVector;
|
import org.apache.druid.math.expr.vector.ExprEvalObjectVector;
|
||||||
import org.apache.druid.math.expr.vector.ExprEvalVector;
|
import org.apache.druid.math.expr.vector.ExprEvalVector;
|
||||||
import org.apache.druid.math.expr.vector.ExprVectorProcessor;
|
import org.apache.druid.math.expr.vector.ExprVectorProcessor;
|
||||||
import org.easymock.EasyMock;
|
import org.easymock.EasyMock;
|
||||||
|
@ -57,7 +57,7 @@ public class ExpressionVectorObjectSelectorTest
|
||||||
public void testSelectObject()
|
public void testSelectObject()
|
||||||
{
|
{
|
||||||
final String[] vector = new String[]{"1", "2", null, "3"};
|
final String[] vector = new String[]{"1", "2", null, "3"};
|
||||||
ExprEvalVector vectorEval = new ExprEvalStringVector(vector);
|
ExprEvalVector vectorEval = new ExprEvalObjectVector(vector);
|
||||||
EasyMock.expect(binding.getCurrentVectorId()).andReturn(1).anyTimes();
|
EasyMock.expect(binding.getCurrentVectorId()).andReturn(1).anyTimes();
|
||||||
EasyMock.expect(vectorProcessor.evalVector(binding)).andReturn(vectorEval).once();
|
EasyMock.expect(vectorProcessor.evalVector(binding)).andReturn(vectorEval).once();
|
||||||
EasyMock.replay(binding, vectorProcessor);
|
EasyMock.replay(binding, vectorProcessor);
|
||||||
|
|
|
@ -43,6 +43,7 @@ import org.apache.druid.segment.vector.SingleValueDimensionVectorSelector;
|
||||||
import org.apache.druid.segment.vector.VectorCursor;
|
import org.apache.druid.segment.vector.VectorCursor;
|
||||||
import org.apache.druid.segment.vector.VectorObjectSelector;
|
import org.apache.druid.segment.vector.VectorObjectSelector;
|
||||||
import org.apache.druid.segment.vector.VectorValueSelector;
|
import org.apache.druid.segment.vector.VectorValueSelector;
|
||||||
|
import org.apache.druid.testing.InitializedNullHandlingTest;
|
||||||
import org.apache.druid.timeline.DataSegment;
|
import org.apache.druid.timeline.DataSegment;
|
||||||
import org.apache.druid.timeline.partition.LinearShardSpec;
|
import org.apache.druid.timeline.partition.LinearShardSpec;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
|
@ -60,7 +61,7 @@ import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@RunWith(Parameterized.class)
|
@RunWith(Parameterized.class)
|
||||||
public class ExpressionVectorSelectorsTest
|
public class ExpressionVectorSelectorsTest extends InitializedNullHandlingTest
|
||||||
{
|
{
|
||||||
private static List<String> EXPRESSIONS = ImmutableList.of(
|
private static List<String> EXPRESSIONS = ImmutableList.of(
|
||||||
"long1 * long2",
|
"long1 * long2",
|
||||||
|
|
Loading…
Reference in New Issue