move numeric null value coercion out of expression processing engine (#13809)

* move numeric null value coercion out of expression processing engine
* add ExprEval.valueOrDefault() to allow consumers to automatically coerce to default values
* rename Expr.buildVectorized as Expr.asVectorProcessor more consistent naming with Function and ApplyFunction; javadocs for some stuff
This commit is contained in:
Clint Wylie 2023-02-28 18:10:07 -08:00 committed by GitHub
parent faf602108b
commit 6cf754b0e0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
40 changed files with 713 additions and 597 deletions

View File

@ -57,9 +57,9 @@ public interface ApplyFunction extends NamedFunction
/**
* Builds a 'vectorized' function expression processor, that can build vectorized processors for its input values
* using {@link Expr#buildVectorized}, for use in vectorized query engines.
* using {@link Expr#asVectorProcessor}, for use in vectorized query engines.
*
* @see Expr#buildVectorized(Expr.VectorInputBindingInspector)
* @see Expr#asVectorProcessor(Expr.VectorInputBindingInspector)
* @see Function#asVectorProcessor(Expr.VectorInputBindingInspector, List)
*/
default <T> ExprVectorProcessor<T> asVectorProcessor(

View File

@ -70,7 +70,7 @@ class BinLtExpr extends BinaryBooleanOpExprBase
}
@Override
public <T> ExprVectorProcessor<T> buildVectorized(VectorInputBindingInspector inspector)
public <T> ExprVectorProcessor<T> asVectorProcessor(VectorInputBindingInspector inspector)
{
return VectorComparisonProcessors.lessThan(inspector, left, right);
}
@ -116,7 +116,7 @@ class BinLeqExpr extends BinaryBooleanOpExprBase
}
@Override
public <T> ExprVectorProcessor<T> buildVectorized(VectorInputBindingInspector inspector)
public <T> ExprVectorProcessor<T> asVectorProcessor(VectorInputBindingInspector inspector)
{
return VectorComparisonProcessors.lessThanOrEqual(inspector, left, right);
}
@ -162,7 +162,7 @@ class BinGtExpr extends BinaryBooleanOpExprBase
}
@Override
public <T> ExprVectorProcessor<T> buildVectorized(VectorInputBindingInspector inspector)
public <T> ExprVectorProcessor<T> asVectorProcessor(VectorInputBindingInspector inspector)
{
return VectorComparisonProcessors.greaterThan(inspector, left, right);
}
@ -208,7 +208,7 @@ class BinGeqExpr extends BinaryBooleanOpExprBase
}
@Override
public <T> ExprVectorProcessor<T> buildVectorized(VectorInputBindingInspector inspector)
public <T> ExprVectorProcessor<T> asVectorProcessor(VectorInputBindingInspector inspector)
{
return VectorComparisonProcessors.greaterThanOrEqual(inspector, left, right);
}
@ -253,7 +253,7 @@ class BinEqExpr extends BinaryBooleanOpExprBase
}
@Override
public <T> ExprVectorProcessor<T> buildVectorized(VectorInputBindingInspector inspector)
public <T> ExprVectorProcessor<T> asVectorProcessor(VectorInputBindingInspector inspector)
{
return VectorComparisonProcessors.equal(inspector, left, right);
}
@ -298,7 +298,7 @@ class BinNeqExpr extends BinaryBooleanOpExprBase
}
@Override
public <T> ExprVectorProcessor<T> buildVectorized(VectorInputBindingInspector inspector)
public <T> ExprVectorProcessor<T> asVectorProcessor(VectorInputBindingInspector inspector)
{
return VectorComparisonProcessors.notEqual(inspector, left, right);
}
@ -331,7 +331,9 @@ class BinAndExpr extends BinaryOpExprBase
return ExprEval.ofLongBoolean(false);
}
ExprEval rightVal;
if (NullHandling.sqlCompatible() || Types.is(leftVal.type(), ExprType.STRING)) {
// null values can (but not always) appear as string typed
// so type isn't necessarily string unless value is non-null
if (NullHandling.sqlCompatible() || (Types.is(leftVal.type(), ExprType.STRING))) {
// true/null, null/true, null/null -> null
// false/null, null/false -> false
if (leftVal.value() == null) {
@ -362,7 +364,7 @@ class BinAndExpr extends BinaryOpExprBase
}
@Override
public <T> ExprVectorProcessor<T> buildVectorized(VectorInputBindingInspector inspector)
public <T> ExprVectorProcessor<T> asVectorProcessor(VectorInputBindingInspector inspector)
{
return VectorProcessors.and(inspector, left, right);
}
@ -405,7 +407,9 @@ class BinOrExpr extends BinaryOpExprBase
}
final ExprEval rightVal;
if (NullHandling.sqlCompatible() || Types.is(leftVal.type(), ExprType.STRING)) {
// null values can (but not always) appear as string typed
// so type isn't necessarily string unless value is non-null
if (NullHandling.sqlCompatible() || (Types.is(leftVal.type(), ExprType.STRING))) {
// true/null, null/true -> true
// false/null, null/false, null/null -> null
if (leftVal.value() == null) {
@ -438,7 +442,7 @@ class BinOrExpr extends BinaryOpExprBase
}
@Override
public <T> ExprVectorProcessor<T> buildVectorized(VectorInputBindingInspector inspector)
public <T> ExprVectorProcessor<T> asVectorProcessor(VectorInputBindingInspector inspector)
{
return VectorProcessors.or(inspector, left, right);
}

View File

@ -70,7 +70,7 @@ final class BinPlusExpr extends BinaryEvalOpExprBase
}
@Override
public <T> ExprVectorProcessor<T> buildVectorized(VectorInputBindingInspector inspector)
public <T> ExprVectorProcessor<T> asVectorProcessor(VectorInputBindingInspector inspector)
{
ExpressionType type = ExpressionTypeConversion.operator(
left.getOutputType(inspector),
@ -116,7 +116,7 @@ final class BinMinusExpr extends BinaryEvalOpExprBase
}
@Override
public <T> ExprVectorProcessor<T> buildVectorized(VectorInputBindingInspector inspector)
public <T> ExprVectorProcessor<T> asVectorProcessor(VectorInputBindingInspector inspector)
{
return VectorMathProcessors.minus(inspector, left, right);
}
@ -155,7 +155,7 @@ final class BinMulExpr extends BinaryEvalOpExprBase
}
@Override
public <T> ExprVectorProcessor<T> buildVectorized(VectorInputBindingInspector inspector)
public <T> ExprVectorProcessor<T> asVectorProcessor(VectorInputBindingInspector inspector)
{
return VectorMathProcessors.multiply(inspector, left, right);
}
@ -194,7 +194,7 @@ final class BinDivExpr extends BinaryEvalOpExprBase
}
@Override
public <T> ExprVectorProcessor<T> buildVectorized(VectorInputBindingInspector inspector)
public <T> ExprVectorProcessor<T> asVectorProcessor(VectorInputBindingInspector inspector)
{
return VectorMathProcessors.divide(inspector, left, right);
}
@ -233,7 +233,7 @@ class BinPowExpr extends BinaryEvalOpExprBase
}
@Override
public <T> ExprVectorProcessor<T> buildVectorized(VectorInputBindingInspector inspector)
public <T> ExprVectorProcessor<T> asVectorProcessor(VectorInputBindingInspector inspector)
{
return VectorMathProcessors.power(inspector, left, right);
}
@ -272,7 +272,7 @@ class BinModuloExpr extends BinaryEvalOpExprBase
}
@Override
public <T> ExprVectorProcessor<T> buildVectorized(VectorInputBindingInspector inspector)
public <T> ExprVectorProcessor<T> asVectorProcessor(VectorInputBindingInspector inspector)
{
return VectorMathProcessors.modulo(inspector, left, right);
}

View File

@ -175,7 +175,7 @@ class LongExpr extends ConstantExpr<Long>
}
@Override
public <T> ExprVectorProcessor<T> buildVectorized(VectorInputBindingInspector inspector)
public <T> ExprVectorProcessor<T> asVectorProcessor(VectorInputBindingInspector inspector)
{
return VectorProcessors.constant(value, inspector.getMaxVectorSize());
}
@ -214,7 +214,7 @@ class NullLongExpr extends ConstantExpr<Long>
}
@Override
public <T> ExprVectorProcessor<T> buildVectorized(VectorInputBindingInspector inspector)
public <T> ExprVectorProcessor<T> asVectorProcessor(VectorInputBindingInspector inspector)
{
return VectorProcessors.constant((Long) null, inspector.getMaxVectorSize());
}
@ -258,7 +258,7 @@ class DoubleExpr extends ConstantExpr<Double>
}
@Override
public <T> ExprVectorProcessor<T> buildVectorized(VectorInputBindingInspector inspector)
public <T> ExprVectorProcessor<T> asVectorProcessor(VectorInputBindingInspector inspector)
{
return VectorProcessors.constant(value, inspector.getMaxVectorSize());
}
@ -297,7 +297,7 @@ class NullDoubleExpr extends ConstantExpr<Double>
}
@Override
public <T> ExprVectorProcessor<T> buildVectorized(VectorInputBindingInspector inspector)
public <T> ExprVectorProcessor<T> asVectorProcessor(VectorInputBindingInspector inspector)
{
return VectorProcessors.constant((Double) null, inspector.getMaxVectorSize());
}
@ -341,7 +341,7 @@ class StringExpr extends ConstantExpr<String>
}
@Override
public <T> ExprVectorProcessor<T> buildVectorized(VectorInputBindingInspector inspector)
public <T> ExprVectorProcessor<T> asVectorProcessor(VectorInputBindingInspector inspector)
{
return VectorProcessors.constant(value, inspector.getMaxVectorSize());
}

View File

@ -164,7 +164,7 @@ public interface Expr extends Cacheable
/**
* Check if an expression can be 'vectorized', for a given set of inputs. If this method returns true,
* {@link #buildVectorized} is expected to produce a {@link ExprVectorProcessor} which can evaluate values in batches
* {@link #asVectorProcessor} is expected to produce a {@link ExprVectorProcessor} which can evaluate values in batches
* to use with vectorized query engines.
*
* @param inspector
@ -180,7 +180,7 @@ public interface Expr extends Cacheable
*
* @param inspector
*/
default <T> ExprVectorProcessor<T> buildVectorized(VectorInputBindingInspector inspector)
default <T> ExprVectorProcessor<T> asVectorProcessor(VectorInputBindingInspector inspector)
{
throw Exprs.cannotVectorize(this);
}
@ -345,7 +345,7 @@ public interface Expr extends Cacheable
}
/**
* {@link InputBindingInspector} + vectorizations stuff for {@link #buildVectorized}
* {@link InputBindingInspector} + vectorizations stuff for {@link #asVectorProcessor}
*/
interface VectorInputBindingInspector extends InputBindingInspector
{

View File

@ -109,14 +109,14 @@ public abstract class ExprEval<T>
int offset = position;
switch (type.getType()) {
case LONG:
if (eval.isNumericNull()) {
if (eval.value() == null) {
TypeStrategies.writeNull(buffer, offset);
} else {
TypeStrategies.writeNotNullNullableLong(buffer, offset, eval.asLong());
}
break;
case DOUBLE:
if (eval.isNumericNull()) {
if (eval.value() == null) {
TypeStrategies.writeNull(buffer, offset);
} else {
TypeStrategies.writeNotNullNullableDouble(buffer, offset, eval.asDouble());
@ -163,14 +163,14 @@ public abstract class ExprEval<T>
Object[] array = new Object[val.size()];
int i = 0;
for (Object o : val) {
array[i++] = o == null ? null : ExprEval.ofType(ExpressionType.LONG, o).value();
array[i++] = o != null ? ExprEval.ofType(ExpressionType.LONG, o).value() : null;
}
return new NonnullPair<>(ExpressionType.LONG_ARRAY, array);
} else if (coercedType == Float.class || coercedType == Double.class) {
Object[] array = new Object[val.size()];
int i = 0;
for (Object o : val) {
array[i++] = ExprEval.ofType(ExpressionType.DOUBLE, o).value();
array[i++] = o != null ? ExprEval.ofType(ExpressionType.DOUBLE, o).value() : null;
}
return new NonnullPair<>(ExpressionType.DOUBLE_ARRAY, array);
} else if (coercedType == Object.class) {
@ -205,7 +205,7 @@ public abstract class ExprEval<T>
Object[] array = new Object[val.size()];
int i = 0;
for (Object o : val) {
array[i++] = o == null ? null : ExprEval.ofType(ExpressionType.STRING, o).value();
array[i++] = o != null ? ExprEval.ofType(ExpressionType.STRING, o).value() : null;
}
return new NonnullPair<>(ExpressionType.STRING_ARRAY, array);
}
@ -345,7 +345,6 @@ public abstract class ExprEval<T>
@Deprecated
public static ExprEval ofBoolean(boolean value, ExprType type)
{
assert !ExpressionProcessing.useStrictBooleans();
switch (type) {
case DOUBLE:
return ExprEval.of(Evals.asDouble(value));
@ -398,7 +397,7 @@ public abstract class ExprEval<T>
final Long[] inputArray = (Long[]) val;
final Object[] array = new Object[inputArray.length];
for (int i = 0; i < inputArray.length; i++) {
array[i] = inputArray[i] != null ? inputArray[i] : NullHandling.defaultLongValue();
array[i] = inputArray[i];
}
return new ArrayExprEval(ExpressionType.LONG_ARRAY, array);
}
@ -414,7 +413,7 @@ public abstract class ExprEval<T>
final Integer[] inputArray = (Integer[]) val;
final Object[] array = new Object[inputArray.length];
for (int i = 0; i < inputArray.length; i++) {
array[i] = inputArray[i] != null ? inputArray[i].longValue() : NullHandling.defaultLongValue();
array[i] = inputArray[i] != null ? inputArray[i].longValue() : null;
}
return new ArrayExprEval(ExpressionType.LONG_ARRAY, array);
}
@ -430,7 +429,7 @@ public abstract class ExprEval<T>
final Double[] inputArray = (Double[]) val;
final Object[] array = new Object[inputArray.length];
for (int i = 0; i < inputArray.length; i++) {
array[i] = inputArray[i] != null ? inputArray[i] : NullHandling.defaultDoubleValue();
array[i] = inputArray[i] != null ? inputArray[i] : null;
}
return new ArrayExprEval(ExpressionType.DOUBLE_ARRAY, array);
}
@ -446,7 +445,7 @@ public abstract class ExprEval<T>
final Float[] inputArray = (Float[]) val;
final Object[] array = new Object[inputArray.length];
for (int i = 0; i < inputArray.length; i++) {
array[i] = inputArray[i] != null ? inputArray[i].doubleValue() : NullHandling.defaultDoubleValue();
array[i] = inputArray[i] != null ? inputArray[i].doubleValue() : null;
}
return new ArrayExprEval(ExpressionType.DOUBLE_ARRAY, array);
}
@ -561,7 +560,6 @@ public abstract class ExprEval<T>
if (bytes != null) {
TypeStrategy<?> strategy = type.getStrategy();
assert strategy != null;
ByteBuffer bb = ByteBuffer.wrap(bytes);
return ofComplex(type, strategy.read(bb));
}
@ -653,6 +651,12 @@ public abstract class ExprEval<T>
return value;
}
@Nullable
public T valueOrDefault()
{
return value;
}
void cacheStringValue(@Nullable String value)
{
stringValue = value;
@ -662,7 +666,6 @@ public abstract class ExprEval<T>
@Nullable
String getCachedStringValue()
{
assert stringValueCached;
return stringValue;
}
@ -743,25 +746,34 @@ public abstract class ExprEval<T>
@Override
public final int asInt()
{
if (value == null) {
return 0;
}
return value.intValue();
}
@Override
public final long asLong()
{
if (value == null) {
return 0L;
}
return value.longValue();
}
@Override
public final double asDouble()
{
if (value == null) {
return 0.0;
}
return value.doubleValue();
}
@Override
public boolean isNumericNull()
{
return value == null;
return NullHandling.sqlCompatible() && value == null;
}
}
@ -771,7 +783,7 @@ public abstract class ExprEval<T>
private DoubleExprEval(@Nullable Number value)
{
super(value == null ? NullHandling.defaultDoubleValue() : (Double) value.doubleValue());
super(value == null ? null : value.doubleValue());
}
@Override
@ -780,6 +792,15 @@ public abstract class ExprEval<T>
return ExpressionType.DOUBLE;
}
@Override
public Number valueOrDefault()
{
if (value == null) {
return NullHandling.defaultDoubleValue();
}
return value;
}
@Override
public final boolean asBoolean()
{
@ -823,7 +844,7 @@ public abstract class ExprEval<T>
@Override
public Expr toExpr()
{
if (isNumericNull()) {
if (value == null) {
return new NullDoubleExpr();
}
return new DoubleExpr(value.doubleValue());
@ -836,7 +857,7 @@ public abstract class ExprEval<T>
private LongExprEval(@Nullable Number value)
{
super(value == null ? NullHandling.defaultLongValue() : (Long) value.longValue());
super(value == null ? null : value.longValue());
}
@Override
@ -845,6 +866,15 @@ public abstract class ExprEval<T>
return ExpressionType.LONG;
}
@Override
public Number valueOrDefault()
{
if (value == null) {
return NullHandling.defaultLongValue();
}
return value;
}
@Override
public final boolean asBoolean()
{
@ -888,7 +918,7 @@ public abstract class ExprEval<T>
@Override
public Expr toExpr()
{
if (isNumericNull()) {
if (value == null) {
return new NullLongExpr();
}
return new LongExpr(value.longValue());
@ -974,7 +1004,6 @@ public abstract class ExprEval<T>
{
Number number = computeNumber();
if (number == null) {
assert NullHandling.replaceWithDefault();
return 0;
}
return number.intValue();
@ -984,7 +1013,6 @@ public abstract class ExprEval<T>
{
Number number = computeNumber();
if (number == null) {
assert NullHandling.replaceWithDefault();
return 0L;
}
return number.longValue();
@ -994,7 +1022,6 @@ public abstract class ExprEval<T>
{
Number number = computeNumber();
if (number == null) {
assert NullHandling.replaceWithDefault();
return 0.0d;
}
return number.doubleValue();
@ -1042,11 +1069,16 @@ public abstract class ExprEval<T>
case STRING:
return this;
case ARRAY:
final Number number = computeNumber();
switch (castTo.getElementType().getType()) {
case DOUBLE:
return ExprEval.ofDoubleArray(value == null ? null : new Object[] {computeDouble()});
return ExprEval.ofDoubleArray(
value == null ? null : new Object[] {number == null ? null : number.doubleValue()}
);
case LONG:
return ExprEval.ofLongArray(value == null ? null : new Object[] {computeLong()});
return ExprEval.ofLongArray(
value == null ? null : new Object[] {number == null ? null : number.longValue()}
);
case STRING:
return ExprEval.ofStringArray(value == null ? null : new Object[] {value});
}
@ -1131,7 +1163,6 @@ public abstract class ExprEval<T>
scalar = computeNumber((String) getScalarValue());
}
if (scalar == null) {
assert NullHandling.replaceWithDefault();
return 0;
}
return scalar.intValue();
@ -1150,7 +1181,6 @@ public abstract class ExprEval<T>
scalar = computeNumber((String) getScalarValue());
}
if (scalar == null) {
assert NullHandling.replaceWithDefault();
return 0;
}
return scalar.longValue();
@ -1169,7 +1199,6 @@ public abstract class ExprEval<T>
scalar = computeNumber((String) getScalarValue());
}
if (scalar == null) {
assert NullHandling.replaceWithDefault();
return 0.0;
}
return scalar.doubleValue();
@ -1184,7 +1213,6 @@ public abstract class ExprEval<T>
if (arrayType.getElementType().isNumeric()) {
Number scalarValue = (Number) getScalarValue();
if (scalarValue == null) {
assert NullHandling.replaceWithDefault();
return false;
}
return Evals.asBoolean(scalarValue.longValue());
@ -1257,7 +1285,6 @@ public abstract class ExprEval<T>
@Nullable
protected Object getScalarValue()
{
assert value != null && value.length == 1;
return value[0];
}
}

View File

@ -131,9 +131,9 @@ public interface Function extends NamedFunction
/**
* Builds a 'vectorized' function expression processor, that can build vectorized processors for its input values
* using {@link Expr#buildVectorized}, for use in vectorized query engines.
* using {@link Expr#asVectorProcessor}, for use in vectorized query engines.
*
* @see Expr#buildVectorized(Expr.VectorInputBindingInspector)
* @see Expr#asVectorProcessor(Expr.VectorInputBindingInspector)
* @see ApplyFunction#asVectorProcessor(Expr.VectorInputBindingInspector, Expr, List)
*/
default <T> ExprVectorProcessor<T> asVectorProcessor(Expr.VectorInputBindingInspector inspector, List<Expr> args)
@ -1176,7 +1176,7 @@ public interface Function extends NamedFunction
{
if (y == 0) {
if (x != 0) {
return ExprEval.ofLong(NullHandling.defaultLongValue());
return ExprEval.ofLong(null);
}
return ExprEval.ofLong(0);
}
@ -1188,7 +1188,7 @@ public interface Function extends NamedFunction
{
if (y == 0 || Double.isNaN(y)) {
if (x != 0) {
return ExprEval.ofDouble(NullHandling.defaultDoubleValue());
return ExprEval.ofDouble(null);
}
return ExprEval.ofDouble(0);
}
@ -2014,7 +2014,7 @@ public interface Function extends NamedFunction
public <T> ExprVectorProcessor<T> asVectorProcessor(Expr.VectorInputBindingInspector inspector, List<Expr> args)
{
return CastToTypeVectorProcessor.cast(
args.get(0).buildVectorized(inspector),
args.get(0).asVectorProcessor(inspector),
ExpressionType.fromString(StringUtils.toUpperCase(args.get(1).getLiteralValue().toString()))
);
}
@ -2384,7 +2384,7 @@ public interface Function extends NamedFunction
public ExprEval apply(List<Expr> args, Expr.ObjectBinding bindings)
{
final String arg = args.get(0).eval(bindings).asString();
return arg == null ? ExprEval.ofLong(NullHandling.defaultLongValue()) : ExprEval.of(arg.length());
return arg == null ? ExprEval.ofLong(null) : ExprEval.of(arg.length());
}
@Override

View File

@ -90,9 +90,9 @@ class LambdaExpr implements Expr
}
@Override
public <T> ExprVectorProcessor<T> buildVectorized(VectorInputBindingInspector inspector)
public <T> ExprVectorProcessor<T> asVectorProcessor(VectorInputBindingInspector inspector)
{
return expr.buildVectorized(inspector);
return expr.asVectorProcessor(inspector);
}
@Override
@ -190,7 +190,7 @@ class FunctionExpr implements Expr
}
@Override
public ExprVectorProcessor<?> buildVectorized(VectorInputBindingInspector inspector)
public ExprVectorProcessor<?> asVectorProcessor(VectorInputBindingInspector inspector)
{
return function.asVectorProcessor(inspector, args);
}
@ -313,7 +313,7 @@ class ApplyFunctionExpr implements Expr
}
@Override
public <T> ExprVectorProcessor<T> buildVectorized(VectorInputBindingInspector inspector)
public <T> ExprVectorProcessor<T> asVectorProcessor(VectorInputBindingInspector inspector)
{
return function.asVectorProcessor(inspector, lambdaExpr, argsExpr);
}

View File

@ -147,7 +147,7 @@ class IdentifierExpr implements Expr
}
@Override
public ExprVectorProcessor<?> buildVectorized(VectorInputBindingInspector inspector)
public ExprVectorProcessor<?> asVectorProcessor(VectorInputBindingInspector inspector)
{
return VectorProcessors.identifier(inspector, binding);
}

View File

@ -147,7 +147,7 @@ class UnaryMinusExpr extends UnaryExpr
}
@Override
public <T> ExprVectorProcessor<T> buildVectorized(VectorInputBindingInspector inspector)
public <T> ExprVectorProcessor<T> asVectorProcessor(VectorInputBindingInspector inspector)
{
return VectorMathProcessors.negate(inspector, expr);
}
@ -203,7 +203,7 @@ class UnaryNotExpr extends UnaryExpr
}
@Override
public <T> ExprVectorProcessor<T> buildVectorized(VectorInputBindingInspector inspector)
public <T> ExprVectorProcessor<T> asVectorProcessor(VectorInputBindingInspector inspector)
{
return VectorProcessors.not(inspector, expr);
}

View File

@ -19,11 +19,9 @@
package org.apache.druid.math.expr.vector;
import org.apache.druid.common.config.NullHandling;
import org.apache.druid.math.expr.ExpressionType;
import javax.annotation.Nullable;
import java.lang.reflect.Array;
/**
* Result of {@link ExprVectorProcessor#evalVector} which wraps the actual evaluated results of the operation over the
@ -48,15 +46,6 @@ public abstract class ExprEvalVector<T>
return values;
}
@Nullable
public Object get(int index)
{
if (nulls == null || NullHandling.replaceWithDefault() || !nulls[index]) {
return Array.get(values, index);
}
return null;
}
@Nullable
public boolean[] getNullVector()
{

View File

@ -19,6 +19,7 @@
package org.apache.druid.math.expr.vector;
import org.apache.druid.common.config.NullHandling;
import org.apache.druid.math.expr.ExpressionType;
import javax.annotation.Nullable;
@ -52,7 +53,7 @@ public abstract class LongOutObjectsInFunctionVectorProcessor
final Long outVal = processValue(in1[i], in2[i]);
if (outVal == null) {
outValues[i] = 0L;
outNulls[i] = true;
outNulls[i] = NullHandling.sqlCompatible();
} else {
outValues[i] = outVal;
outNulls[i] = false;
@ -63,7 +64,7 @@ public abstract class LongOutObjectsInFunctionVectorProcessor
void processNull(int i)
{
outValues[i] = 0L;
outNulls[i] = true;
outNulls[i] = NullHandling.sqlCompatible();
}
@Override

View File

@ -137,8 +137,8 @@ public class VectorComparisonProcessors
left,
right,
() -> new LongOutObjectsInFunctionVectorProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize(),
ExpressionType.STRING
)
@ -151,8 +151,8 @@ public class VectorComparisonProcessors
}
},
() -> new LongOutLongsInFunctionVectorValueProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize()
)
{
@ -163,8 +163,8 @@ public class VectorComparisonProcessors
}
},
() -> new DoubleOutLongDoubleInFunctionVectorValueProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize()
)
{
@ -175,8 +175,8 @@ public class VectorComparisonProcessors
}
},
() -> new DoubleOutDoubleLongInFunctionVectorValueProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize()
)
{
@ -187,8 +187,8 @@ public class VectorComparisonProcessors
}
},
() -> new DoubleOutDoublesInFunctionVectorValueProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize()
)
{
@ -205,8 +205,8 @@ public class VectorComparisonProcessors
left,
right,
() -> new LongOutObjectsInFunctionVectorProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize(),
ExpressionType.STRING
)
@ -219,8 +219,8 @@ public class VectorComparisonProcessors
}
},
() -> new LongOutLongsInFunctionVectorValueProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize()
)
{
@ -231,8 +231,8 @@ public class VectorComparisonProcessors
}
},
() -> new LongOutLongDoubleInFunctionVectorValueProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize()
)
{
@ -243,8 +243,8 @@ public class VectorComparisonProcessors
}
},
() -> new LongOutDoubleLongInFunctionVectorValueProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize()
)
{
@ -255,8 +255,8 @@ public class VectorComparisonProcessors
}
},
() -> new LongOutDoublesInFunctionVectorValueProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize()
)
{
@ -281,8 +281,8 @@ public class VectorComparisonProcessors
left,
right,
() -> new LongOutObjectsInFunctionVectorProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize(),
ExpressionType.STRING
)
@ -295,8 +295,8 @@ public class VectorComparisonProcessors
}
},
() -> new LongOutLongsInFunctionVectorValueProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize()
)
{
@ -307,8 +307,8 @@ public class VectorComparisonProcessors
}
},
() -> new DoubleOutLongDoubleInFunctionVectorValueProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize()
)
{
@ -319,8 +319,8 @@ public class VectorComparisonProcessors
}
},
() -> new DoubleOutDoubleLongInFunctionVectorValueProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize()
)
{
@ -331,8 +331,8 @@ public class VectorComparisonProcessors
}
},
() -> new DoubleOutDoublesInFunctionVectorValueProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize()
)
{
@ -349,8 +349,8 @@ public class VectorComparisonProcessors
left,
right,
() -> new LongOutObjectsInFunctionVectorProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize(),
ExpressionType.STRING
)
@ -363,8 +363,8 @@ public class VectorComparisonProcessors
}
},
() -> new LongOutLongsInFunctionVectorValueProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize()
)
{
@ -375,8 +375,8 @@ public class VectorComparisonProcessors
}
},
() -> new LongOutLongDoubleInFunctionVectorValueProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize()
)
{
@ -387,8 +387,8 @@ public class VectorComparisonProcessors
}
},
() -> new LongOutDoubleLongInFunctionVectorValueProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize()
)
{
@ -399,8 +399,8 @@ public class VectorComparisonProcessors
}
},
() -> new LongOutDoublesInFunctionVectorValueProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize()
)
{
@ -425,8 +425,8 @@ public class VectorComparisonProcessors
left,
right,
() -> new LongOutObjectsInFunctionVectorProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize(),
ExpressionType.STRING
)
@ -441,8 +441,8 @@ public class VectorComparisonProcessors
}
},
() -> new LongOutLongsInFunctionVectorValueProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize()
)
{
@ -453,8 +453,8 @@ public class VectorComparisonProcessors
}
},
() -> new DoubleOutLongDoubleInFunctionVectorValueProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize()
)
{
@ -465,8 +465,8 @@ public class VectorComparisonProcessors
}
},
() -> new DoubleOutDoubleLongInFunctionVectorValueProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize()
)
{
@ -477,8 +477,8 @@ public class VectorComparisonProcessors
}
},
() -> new DoubleOutDoublesInFunctionVectorValueProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize()
)
{
@ -495,8 +495,8 @@ public class VectorComparisonProcessors
left,
right,
() -> new LongOutObjectsInFunctionVectorProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize(),
ExpressionType.STRING
)
@ -511,8 +511,8 @@ public class VectorComparisonProcessors
}
},
() -> new LongOutLongsInFunctionVectorValueProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize()
)
{
@ -523,8 +523,8 @@ public class VectorComparisonProcessors
}
},
() -> new LongOutLongDoubleInFunctionVectorValueProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize()
)
{
@ -535,8 +535,8 @@ public class VectorComparisonProcessors
}
},
() -> new LongOutDoubleLongInFunctionVectorValueProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize()
)
{
@ -547,8 +547,8 @@ public class VectorComparisonProcessors
}
},
() -> new LongOutDoublesInFunctionVectorValueProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize()
)
{
@ -573,8 +573,8 @@ public class VectorComparisonProcessors
left,
right,
() -> new LongOutObjectsInFunctionVectorProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize(),
ExpressionType.STRING
)
@ -589,8 +589,8 @@ public class VectorComparisonProcessors
}
},
() -> new LongOutLongsInFunctionVectorValueProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize()
)
{
@ -601,8 +601,8 @@ public class VectorComparisonProcessors
}
},
() -> new DoubleOutLongDoubleInFunctionVectorValueProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize()
)
{
@ -613,8 +613,8 @@ public class VectorComparisonProcessors
}
},
() -> new DoubleOutDoubleLongInFunctionVectorValueProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize()
)
{
@ -625,8 +625,8 @@ public class VectorComparisonProcessors
}
},
() -> new DoubleOutDoublesInFunctionVectorValueProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize()
)
{
@ -643,8 +643,8 @@ public class VectorComparisonProcessors
left,
right,
() -> new LongOutObjectsInFunctionVectorProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize(),
ExpressionType.STRING
)
@ -659,8 +659,8 @@ public class VectorComparisonProcessors
}
},
() -> new LongOutLongsInFunctionVectorValueProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize()
)
{
@ -671,8 +671,8 @@ public class VectorComparisonProcessors
}
},
() -> new LongOutLongDoubleInFunctionVectorValueProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize()
)
{
@ -683,8 +683,8 @@ public class VectorComparisonProcessors
}
},
() -> new LongOutDoubleLongInFunctionVectorValueProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize()
)
{
@ -695,8 +695,8 @@ public class VectorComparisonProcessors
}
},
() -> new LongOutDoublesInFunctionVectorValueProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize()
)
{
@ -721,8 +721,8 @@ public class VectorComparisonProcessors
left,
right,
() -> new LongOutObjectsInFunctionVectorProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize(),
ExpressionType.STRING
)
@ -737,8 +737,8 @@ public class VectorComparisonProcessors
}
},
() -> new LongOutLongsInFunctionVectorValueProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize()
)
{
@ -749,8 +749,8 @@ public class VectorComparisonProcessors
}
},
() -> new DoubleOutLongDoubleInFunctionVectorValueProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize()
)
{
@ -761,8 +761,8 @@ public class VectorComparisonProcessors
}
},
() -> new DoubleOutDoubleLongInFunctionVectorValueProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize()
)
{
@ -773,8 +773,8 @@ public class VectorComparisonProcessors
}
},
() -> new DoubleOutDoublesInFunctionVectorValueProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize()
)
{
@ -791,8 +791,8 @@ public class VectorComparisonProcessors
left,
right,
() -> new LongOutObjectsInFunctionVectorProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize(),
ExpressionType.STRING
)
@ -807,8 +807,8 @@ public class VectorComparisonProcessors
}
},
() -> new LongOutLongsInFunctionVectorValueProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize()
)
{
@ -819,8 +819,8 @@ public class VectorComparisonProcessors
}
},
() -> new LongOutLongDoubleInFunctionVectorValueProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize()
)
{
@ -831,8 +831,8 @@ public class VectorComparisonProcessors
}
},
() -> new LongOutDoubleLongInFunctionVectorValueProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize()
)
{
@ -843,8 +843,8 @@ public class VectorComparisonProcessors
}
},
() -> new LongOutDoublesInFunctionVectorValueProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize()
)
{
@ -869,8 +869,8 @@ public class VectorComparisonProcessors
left,
right,
() -> new LongOutObjectsInFunctionVectorProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize(),
ExpressionType.STRING
)
@ -885,8 +885,8 @@ public class VectorComparisonProcessors
}
},
() -> new LongOutLongsInFunctionVectorValueProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize()
)
{
@ -897,8 +897,8 @@ public class VectorComparisonProcessors
}
},
() -> new DoubleOutLongDoubleInFunctionVectorValueProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize()
)
{
@ -909,8 +909,8 @@ public class VectorComparisonProcessors
}
},
() -> new DoubleOutDoubleLongInFunctionVectorValueProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize()
)
{
@ -921,8 +921,8 @@ public class VectorComparisonProcessors
}
},
() -> new DoubleOutDoublesInFunctionVectorValueProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize()
)
{
@ -939,8 +939,8 @@ public class VectorComparisonProcessors
left,
right,
() -> new LongOutObjectsInFunctionVectorProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize(),
ExpressionType.STRING
)
@ -955,8 +955,8 @@ public class VectorComparisonProcessors
}
},
() -> new LongOutLongsInFunctionVectorValueProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize()
)
{
@ -967,8 +967,8 @@ public class VectorComparisonProcessors
}
},
() -> new LongOutLongDoubleInFunctionVectorValueProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize()
)
{
@ -979,8 +979,8 @@ public class VectorComparisonProcessors
}
},
() -> new LongOutDoubleLongInFunctionVectorValueProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize()
)
{
@ -991,8 +991,8 @@ public class VectorComparisonProcessors
}
},
() -> new LongOutDoublesInFunctionVectorValueProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize()
)
{

View File

@ -55,7 +55,7 @@ public class VectorProcessors
// if type is null, it means the input is all nulls
if (leftType == null) {
return right.buildVectorized(inspector);
return right.asVectorProcessor(inspector);
}
Preconditions.checkArgument(
@ -80,6 +80,11 @@ public class VectorProcessors
return (ExprVectorProcessor<T>) processor;
}
/**
* Creates an {@link ExprVectorProcessor} that creates a {@link ExprEvalVector} for a constant {@link String} value.
*
* @see org.apache.druid.math.expr.ConstantExpr
*/
public static <T> ExprVectorProcessor<T> constant(@Nullable String constant, int maxVectorSize)
{
final Object[] strings = new Object[maxVectorSize];
@ -101,13 +106,18 @@ public class VectorProcessors
};
}
/**
* Creates an {@link ExprVectorProcessor} that creates a {@link ExprEvalVector} for a constant {@link Double} value.
*
* @see org.apache.druid.math.expr.ConstantExpr
*/
public static <T> ExprVectorProcessor<T> constant(@Nullable Double constant, int maxVectorSize)
{
final double[] doubles = new double[maxVectorSize];
final boolean[] nulls;
if (constant == null) {
nulls = new boolean[maxVectorSize];
Arrays.fill(nulls, true);
Arrays.fill(nulls, NullHandling.sqlCompatible());
} else {
nulls = null;
Arrays.fill(doubles, constant);
@ -129,13 +139,18 @@ public class VectorProcessors
};
}
/**
* Creates an {@link ExprVectorProcessor} that creates a {@link ExprEvalVector} for a constant {@link Long} value.
*
* @see org.apache.druid.math.expr.ConstantExpr
*/
public static <T> ExprVectorProcessor<T> constant(@Nullable Long constant, int maxVectorSize)
{
final long[] longs = new long[maxVectorSize];
final boolean[] nulls;
if (constant == null) {
nulls = new boolean[maxVectorSize];
Arrays.fill(nulls, true);
Arrays.fill(nulls, NullHandling.sqlCompatible());
} else {
nulls = null;
Arrays.fill(longs, constant);
@ -157,6 +172,14 @@ public class VectorProcessors
};
}
/**
* Creates an {@link ExprVectorProcessor} that creates a {@link ExprEvalVector} for some expression variable input
* binding, typically for segment column value vectors from a
* {@link org.apache.druid.segment.vector.VectorValueSelector} or
* {@link org.apache.druid.segment.vector.VectorObjectSelector}.
*
* @see org.apache.druid.math.expr.IdentifierExpr
*/
public static ExprVectorProcessor<?> identifier(Expr.VectorInputBindingInspector inspector, String binding)
{
ExpressionType inputType = inspector.getType(binding);
@ -206,10 +229,15 @@ public class VectorProcessors
}
}
/**
* Creates an {@link ExprVectorProcessor} that will parse a string into a long value given a radix.
*
* @see org.apache.druid.math.expr.Function.ParseLong
*/
public static <T> ExprVectorProcessor<T> parseLong(Expr.VectorInputBindingInspector inspector, Expr arg, int radix)
{
final ExprVectorProcessor<?> processor = new LongOutObjectInFunctionVectorProcessor(
arg.buildVectorized(inspector),
arg.asVectorProcessor(inspector),
inspector.getMaxVectorSize(),
ExpressionType.STRING
)
@ -242,6 +270,12 @@ public class VectorProcessors
return (ExprVectorProcessor<T>) processor;
}
/**
* Creates an {@link ExprVectorProcessor} for the 'isnull' function, that produces a "boolean" typed output
* vector (long[]) with values set to 1 if the input value was null or 0 if it was not null.
*
* @see org.apache.druid.math.expr.Function.IsNullFunc
*/
public static <T> ExprVectorProcessor<T> isNull(Expr.VectorInputBindingInspector inspector, Expr expr)
{
@ -254,7 +288,7 @@ public class VectorProcessors
ExprVectorProcessor<?> processor = null;
if (Types.is(type, ExprType.STRING)) {
final ExprVectorProcessor<Object[]> input = expr.buildVectorized(inspector);
final ExprVectorProcessor<Object[]> input = expr.asVectorProcessor(inspector);
processor = new ExprVectorProcessor<long[]>()
{
@Override
@ -281,7 +315,7 @@ public class VectorProcessors
}
};
} else if (Types.is(type, ExprType.LONG)) {
final ExprVectorProcessor<long[]> input = expr.buildVectorized(inspector);
final ExprVectorProcessor<long[]> input = expr.asVectorProcessor(inspector);
processor = new ExprVectorProcessor<long[]>()
{
@Override
@ -312,7 +346,7 @@ public class VectorProcessors
}
};
} else if (Types.is(type, ExprType.DOUBLE)) {
final ExprVectorProcessor<double[]> input = expr.buildVectorized(inspector);
final ExprVectorProcessor<double[]> input = expr.asVectorProcessor(inspector);
processor = new ExprVectorProcessor<long[]>()
{
@Override
@ -350,6 +384,12 @@ public class VectorProcessors
return (ExprVectorProcessor<T>) processor;
}
/**
* Creates an {@link ExprVectorProcessor} for the 'isnotnull' function, that produces a "boolean" typed output
* vector (long[]) with values set to 1 if the input value was not null or 0 if it was null.
*
* @see org.apache.druid.math.expr.Function.IsNotNullFunc
*/
public static <T> ExprVectorProcessor<T> isNotNull(Expr.VectorInputBindingInspector inspector, Expr expr)
{
@ -362,7 +402,7 @@ public class VectorProcessors
ExprVectorProcessor<?> processor = null;
if (Types.is(type, ExprType.STRING)) {
final ExprVectorProcessor<Object[]> input = expr.buildVectorized(inspector);
final ExprVectorProcessor<Object[]> input = expr.asVectorProcessor(inspector);
processor = new ExprVectorProcessor<long[]>()
{
@Override
@ -389,7 +429,7 @@ public class VectorProcessors
}
};
} else if (Types.is(type, ExprType.LONG)) {
final ExprVectorProcessor<long[]> input = expr.buildVectorized(inspector);
final ExprVectorProcessor<long[]> input = expr.asVectorProcessor(inspector);
processor = new ExprVectorProcessor<long[]>()
{
@Override
@ -420,7 +460,7 @@ public class VectorProcessors
}
};
} else if (Types.is(type, ExprType.DOUBLE)) {
final ExprVectorProcessor<double[]> input = expr.buildVectorized(inspector);
final ExprVectorProcessor<double[]> input = expr.asVectorProcessor(inspector);
processor = new ExprVectorProcessor<long[]>()
{
@Override
@ -458,6 +498,12 @@ public class VectorProcessors
return (ExprVectorProcessor<T>) processor;
}
/**
* Creates an {@link ExprVectorProcessor} for the 'nvl' function, that will return the first argument value if it is
* not null, else the value of the 2nd argument.
*
* @see org.apache.druid.math.expr.Function.NvlFunc
*/
public static <T> ExprVectorProcessor<T> nvl(Expr.VectorInputBindingInspector inspector, Expr left, Expr right)
{
final int maxVectorSize = inspector.getMaxVectorSize();
@ -468,8 +514,8 @@ public class VectorProcessors
right,
() -> new SymmetricalBivariateFunctionVectorProcessor<long[]>(
ExpressionType.LONG,
left.buildVectorized(inspector),
right.buildVectorized(inspector)
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector)
)
{
final long[] output = new long[maxVectorSize];
@ -504,8 +550,8 @@ public class VectorProcessors
},
() -> new SymmetricalBivariateFunctionVectorProcessor<double[]>(
ExpressionType.DOUBLE,
left.buildVectorized(inspector),
right.buildVectorized(inspector)
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector)
)
{
final double[] output = new double[maxVectorSize];
@ -540,8 +586,8 @@ public class VectorProcessors
},
() -> new SymmetricalBivariateFunctionVectorProcessor<Object[]>(
ExpressionType.STRING,
left.buildVectorized(inspector),
right.buildVectorized(inspector)
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector)
)
{
final Object[] output = new Object[maxVectorSize];
@ -567,6 +613,15 @@ public class VectorProcessors
);
}
/**
* Creates an {@link ExprVectorProcessor} for the logical 'not' operator, which produces a long typed vector output
* with values set by the following rules:
* false -> true (1)
* null -> null
* true -> false (0)
*
* @see org.apache.druid.math.expr.UnaryNotExpr
*/
public static <T> ExprVectorProcessor<T> not(Expr.VectorInputBindingInspector inspector, Expr expr)
{
final ExpressionType inputType = expr.getOutputType(inspector);
@ -574,7 +629,7 @@ public class VectorProcessors
ExprVectorProcessor<?> processor = null;
if (Types.is(inputType, ExprType.STRING)) {
processor = new LongOutObjectInFunctionVectorProcessor(
expr.buildVectorized(inspector),
expr.asVectorProcessor(inspector),
maxVectorSize,
ExpressionType.STRING
)
@ -589,7 +644,7 @@ public class VectorProcessors
}
};
} else if (Types.is(inputType, ExprType.LONG)) {
processor = new LongOutLongInFunctionVectorValueProcessor(expr.buildVectorized(inspector), maxVectorSize)
processor = new LongOutLongInFunctionVectorValueProcessor(expr.asVectorProcessor(inspector), maxVectorSize)
{
@Override
public long apply(long input)
@ -599,7 +654,7 @@ public class VectorProcessors
};
} else if (Types.is(inputType, ExprType.DOUBLE)) {
if (!ExpressionProcessing.useStrictBooleans()) {
processor = new DoubleOutDoubleInFunctionVectorValueProcessor(expr.buildVectorized(inspector), maxVectorSize)
processor = new DoubleOutDoubleInFunctionVectorValueProcessor(expr.asVectorProcessor(inspector), maxVectorSize)
{
@Override
public double apply(double input)
@ -608,7 +663,7 @@ public class VectorProcessors
}
};
} else {
processor = new LongOutDoubleInFunctionVectorValueProcessor(expr.buildVectorized(inspector), maxVectorSize)
processor = new LongOutDoubleInFunctionVectorValueProcessor(expr.asVectorProcessor(inspector), maxVectorSize)
{
@Override
public long apply(double input)
@ -624,6 +679,15 @@ public class VectorProcessors
return (ExprVectorProcessor<T>) processor;
}
/**
* Creates an {@link ExprVectorProcessor} for the logical 'or' operator, which produces a long typed vector output
* with values set by the following rules:
* true/null, null/true -> true (1)
* false/null, null/false, null/null -> null
* false/false -> false (0)
*
* @see org.apache.druid.math.expr.BinOrExpr
*/
public static <T> ExprVectorProcessor<T> or(Expr.VectorInputBindingInspector inspector, Expr left, Expr right)
{
final int maxVectorSize = inspector.getMaxVectorSize();
@ -633,8 +697,8 @@ public class VectorProcessors
right,
() -> new SymmetricalBivariateFunctionVectorProcessor<long[]>(
ExpressionType.LONG,
left.buildVectorized(inspector),
right.buildVectorized(inspector)
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector)
)
{
final long[] output = new long[maxVectorSize];
@ -657,7 +721,7 @@ public class VectorProcessors
if (leftNull) {
if (rightNull) {
output[i] = 0L;
outputNulls[i] = true;
outputNulls[i] = NullHandling.sqlCompatible();
return;
}
final boolean bool = Evals.asBoolean(rightInput[i]);
@ -682,8 +746,8 @@ public class VectorProcessors
},
() -> new BivariateFunctionVectorProcessor<double[], double[], long[]>(
ExpressionType.LONG,
left.buildVectorized(inspector),
right.buildVectorized(inspector)
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector)
)
{
final long[] output = new long[maxVectorSize];
@ -706,7 +770,7 @@ public class VectorProcessors
if (leftNull) {
if (rightNull) {
output[i] = 0;
outputNulls[i] = true;
outputNulls[i] = NullHandling.sqlCompatible();
return;
}
final boolean bool = Evals.asBoolean(rightInput[i]);
@ -731,8 +795,8 @@ public class VectorProcessors
},
() -> new BivariateFunctionVectorProcessor<Object[], Object[], long[]>(
ExpressionType.LONG,
left.buildVectorized(inspector),
right.buildVectorized(inspector)
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector)
)
{
final long[] output = new long[maxVectorSize];
@ -753,7 +817,7 @@ public class VectorProcessors
final boolean rightNull = rightInput[i] == null;
if (leftNull) {
if (rightNull) {
outputNulls[i] = true;
outputNulls[i] = NullHandling.sqlCompatible();
return;
}
final boolean bool = Evals.asBoolean((String) rightInput[i]);
@ -778,6 +842,15 @@ public class VectorProcessors
);
}
/**
* Creates an {@link ExprVectorProcessor} for the logical 'and' operator, which produces a long typed vector output
* with values set by the following rules:
* true/true -> true (1)
* true/null, null/true, null/null -> null
* false/null, null/false -> false (0)
*
* @see org.apache.druid.math.expr.BinAndExpr
*/
public static <T> ExprVectorProcessor<T> and(Expr.VectorInputBindingInspector inputTypes, Expr left, Expr right)
{
final int maxVectorSize = inputTypes.getMaxVectorSize();
@ -787,8 +860,8 @@ public class VectorProcessors
right,
() -> new SymmetricalBivariateFunctionVectorProcessor<long[]>(
ExpressionType.LONG,
left.buildVectorized(inputTypes),
right.buildVectorized(inputTypes)
left.asVectorProcessor(inputTypes),
right.asVectorProcessor(inputTypes)
)
{
final long[] output = new long[maxVectorSize];
@ -811,7 +884,7 @@ public class VectorProcessors
if (leftNull) {
if (rightNull) {
output[i] = 0L;
outputNulls[i] = true;
outputNulls[i] = NullHandling.sqlCompatible();
return;
}
final boolean bool = Evals.asBoolean(rightInput[i]);
@ -836,8 +909,8 @@ public class VectorProcessors
},
() -> new BivariateFunctionVectorProcessor<double[], double[], long[]>(
ExpressionType.DOUBLE,
left.buildVectorized(inputTypes),
right.buildVectorized(inputTypes)
left.asVectorProcessor(inputTypes),
right.asVectorProcessor(inputTypes)
)
{
final long[] output = new long[maxVectorSize];
@ -860,7 +933,7 @@ public class VectorProcessors
if (leftNull) {
if (rightNull) {
output[i] = 0L;
outputNulls[i] = true;
outputNulls[i] = NullHandling.sqlCompatible();
return;
}
final boolean bool = Evals.asBoolean(rightInput[i]);
@ -885,8 +958,8 @@ public class VectorProcessors
},
() -> new BivariateFunctionVectorProcessor<Object[], Object[], long[]>(
ExpressionType.STRING,
left.buildVectorized(inputTypes),
right.buildVectorized(inputTypes)
left.asVectorProcessor(inputTypes),
right.asVectorProcessor(inputTypes)
)
{
final long[] output = new long[maxVectorSize];
@ -907,7 +980,7 @@ public class VectorProcessors
final boolean rightNull = rightInput[i] == null;
if (leftNull) {
if (rightNull) {
outputNulls[i] = true;
outputNulls[i] = NullHandling.sqlCompatible();
return;
}
final boolean bool = Evals.asBoolean((String) rightInput[i]);
@ -939,6 +1012,11 @@ public class VectorProcessors
// No instantiation
}
/**
* Basic scaffolding for an 'identifier' {@link ExprVectorProcessor}
*
* @see #identifier
*/
abstract static class IdentifierVectorProcessor<T> implements ExprVectorProcessor<T>
{
private final ExpressionType outputType;

View File

@ -34,8 +34,8 @@ public class VectorStringProcessors
final ExprVectorProcessor processor;
if (NullHandling.sqlCompatible()) {
processor = new ObjectOutObjectsInFunctionVectorProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize(),
ExpressionType.STRING
)
@ -50,8 +50,8 @@ public class VectorStringProcessors
};
} else {
processor = new ObjectOutObjectsInFunctionVectorProcessor(
left.buildVectorized(inspector),
right.buildVectorized(inspector),
left.asVectorProcessor(inspector),
right.asVectorProcessor(inspector),
inspector.getMaxVectorSize(),
ExpressionType.STRING
)
@ -73,7 +73,7 @@ public class VectorStringProcessors
final ExprVectorProcessor<Object[]>[] inputProcessors = new ExprVectorProcessor[inputs.size()];
for (int i = 0; i < inputs.size(); i++) {
inputProcessors[i] = CastToTypeVectorProcessor.cast(
inputs.get(i).buildVectorized(inspector),
inputs.get(i).asVectorProcessor(inspector),
ExpressionType.STRING
);
}

View File

@ -206,7 +206,7 @@ public class AggregatorUtil
* Only one of fieldName and fieldExpression should be non-null
*/
static ColumnValueSelector makeColumnValueSelectorWithFloatDefault(
final ColumnSelectorFactory metricFactory,
final ColumnSelectorFactory columnSelectorFactory,
@Nullable final String fieldName,
@Nullable final Expr fieldExpression,
final float nullValue
@ -216,9 +216,12 @@ public class AggregatorUtil
throw new IllegalArgumentException("Only one of fieldName or expression should be non-null");
}
if (fieldName != null) {
return metricFactory.makeColumnValueSelector(fieldName);
return columnSelectorFactory.makeColumnValueSelector(fieldName);
} else {
final ColumnValueSelector<ExprEval> baseSelector = ExpressionSelectors.makeExprEvalSelector(metricFactory, fieldExpression);
final ColumnValueSelector<ExprEval> baseSelector = ExpressionSelectors.makeExprEvalSelector(
columnSelectorFactory,
fieldExpression
);
class ExpressionFloatColumnSelector implements FloatColumnSelector
{
@Override
@ -226,22 +229,22 @@ public class AggregatorUtil
{
// Although baseSelector.getObject is nullable
// exprEval returned from Expression selectors is never null.
final ExprEval exprEval = baseSelector.getObject();
final ExprEval<?> exprEval = baseSelector.getObject();
return exprEval.isNumericNull() ? nullValue : (float) exprEval.asDouble();
}
@Override
public boolean isNull()
{
final ExprEval<?> exprEval = baseSelector.getObject();
return exprEval == null || exprEval.isNumericNull();
}
@Override
public void inspectRuntimeShape(RuntimeShapeInspector inspector)
{
inspector.visit("baseSelector", baseSelector);
}
@Override
public boolean isNull()
{
final ExprEval exprEval = baseSelector.getObject();
return exprEval == null || exprEval.isNumericNull();
}
}
return new ExpressionFloatColumnSelector();
}
@ -250,8 +253,8 @@ public class AggregatorUtil
/**
* Only one of fieldName and fieldExpression should be non-null
*/
static ColumnValueSelector makeColumnValueSelectorWithLongDefault(
final ColumnSelectorFactory metricFactory,
static ColumnValueSelector<?> makeColumnValueSelectorWithLongDefault(
final ColumnSelectorFactory columnSelectorFactory,
@Nullable final String fieldName,
@Nullable final Expr fieldExpression,
final long nullValue
@ -261,30 +264,33 @@ public class AggregatorUtil
throw new IllegalArgumentException("Only one of fieldName and fieldExpression should be non-null");
}
if (fieldName != null) {
return metricFactory.makeColumnValueSelector(fieldName);
return columnSelectorFactory.makeColumnValueSelector(fieldName);
} else {
final ColumnValueSelector<ExprEval> baseSelector = ExpressionSelectors.makeExprEvalSelector(metricFactory, fieldExpression);
final ColumnValueSelector<ExprEval> baseSelector = ExpressionSelectors.makeExprEvalSelector(
columnSelectorFactory,
fieldExpression
);
class ExpressionLongColumnSelector implements LongColumnSelector
{
@Override
public long getLong()
{
final ExprEval exprEval = baseSelector.getObject();
final ExprEval<?> exprEval = baseSelector.getObject();
return exprEval.isNumericNull() ? nullValue : exprEval.asLong();
}
@Override
public boolean isNull()
{
final ExprEval<?> exprEval = baseSelector.getObject();
return exprEval == null || exprEval.isNumericNull();
}
@Override
public void inspectRuntimeShape(RuntimeShapeInspector inspector)
{
inspector.visit("baseSelector", baseSelector);
}
@Override
public boolean isNull()
{
final ExprEval exprEval = baseSelector.getObject();
return exprEval == null || exprEval.isNumericNull();
}
}
return new ExpressionLongColumnSelector();
}
@ -293,8 +299,8 @@ public class AggregatorUtil
/**
* Only one of fieldName and fieldExpression should be non-null
*/
static ColumnValueSelector makeColumnValueSelectorWithDoubleDefault(
final ColumnSelectorFactory metricFactory,
static ColumnValueSelector<?> makeColumnValueSelectorWithDoubleDefault(
final ColumnSelectorFactory columnSelectorFactory,
@Nullable final String fieldName,
@Nullable final Expr fieldExpression,
final double nullValue
@ -304,30 +310,33 @@ public class AggregatorUtil
throw new IllegalArgumentException("Only one of fieldName and fieldExpression should be non-null");
}
if (fieldName != null) {
return metricFactory.makeColumnValueSelector(fieldName);
return columnSelectorFactory.makeColumnValueSelector(fieldName);
} else {
final ColumnValueSelector<ExprEval> baseSelector = ExpressionSelectors.makeExprEvalSelector(metricFactory, fieldExpression);
final ColumnValueSelector<ExprEval> baseSelector = ExpressionSelectors.makeExprEvalSelector(
columnSelectorFactory,
fieldExpression
);
class ExpressionDoubleColumnSelector implements DoubleColumnSelector
{
@Override
public double getDouble()
{
final ExprEval exprEval = baseSelector.getObject();
final ExprEval<?> exprEval = baseSelector.getObject();
return exprEval.isNumericNull() ? nullValue : exprEval.asDouble();
}
@Override
public boolean isNull()
{
final ExprEval<?> exprEval = baseSelector.getObject();
return exprEval == null || exprEval.isNumericNull();
}
@Override
public void inspectRuntimeShape(RuntimeShapeInspector inspector)
{
inspector.visit("baseSelector", baseSelector);
}
@Override
public boolean isNull()
{
final ExprEval exprEval = baseSelector.getObject();
return exprEval == null || exprEval.isNumericNull();
}
}
return new ExpressionDoubleColumnSelector();
}

View File

@ -59,7 +59,7 @@ public class ExpressionLambdaAggregator implements Aggregator
}
}
final ExprEval<?> eval = lambda.eval(bindings);
final int estimatedSize = eval.type().getNullableStrategy().estimateSizeBytes(eval.value());
final int estimatedSize = eval.type().getNullableStrategy().estimateSizeBytes(eval.valueOrDefault());
if (estimatedSize > maxSizeBytes) {
throw new ISE(
"Exceeded memory usage when aggregating type [%s], size [%s] is larger than max [%s]",
@ -76,7 +76,7 @@ public class ExpressionLambdaAggregator implements Aggregator
@Override
public Object get()
{
return hasValue ? bindings.getAccumulator().value() : null;
return hasValue ? bindings.getAccumulator().valueOrDefault() : null;
}
@Override

View File

@ -346,7 +346,7 @@ public class ExpressionLambdaAggregatorFactory extends AggregatorFactory
// arbitrarily assign lhs and rhs to accumulator and aggregator name inputs to re-use combine function
return combineExpression.get().eval(
combineBindings.get().withBinding(accumulatorId, lhs).withBinding(name, rhs)
).value();
).valueOrDefault();
}
@Override
@ -362,7 +362,7 @@ public class ExpressionLambdaAggregatorFactory extends AggregatorFactory
Expr finalizeExpr;
finalizeExpr = finalizeExpression.get();
if (finalizeExpr != null) {
return finalizeExpr.eval(finalizeBindings.get().withBinding(FINALIZE_IDENTIFIER, object)).value();
return finalizeExpr.eval(finalizeBindings.get().withBinding(FINALIZE_IDENTIFIER, object)).valueOrDefault();
}
return object;
}

View File

@ -53,7 +53,7 @@ public class ExpressionLambdaAggregatorInputBindings implements Expr.ObjectBindi
public Object get(String name)
{
if (accumlatorIdentifier.equals(name)) {
return accumulator.value();
return accumulator.valueOrDefault();
}
return inputBindings.get(name);
}

View File

@ -90,7 +90,7 @@ public class ExpressionLambdaBufferAggregator implements BufferAggregator
if (isNullUnlessAggregated && (buf.get(position) & NOT_AGGREGATED_BIT) != 0) {
return null;
}
return ExprEval.deserialize(buf, position, maxSizeBytes, outputType, false).value();
return ExprEval.deserialize(buf, position, maxSizeBytes, outputType, false).valueOrDefault();
}
@Override

View File

@ -171,7 +171,7 @@ public class ExpressionPostAggregator implements PostAggregator
}
);
return parsed.get().eval(InputBindings.withMap(finalizedValues)).value();
return parsed.get().eval(InputBindings.withMap(finalizedValues)).valueOrDefault();
}
@Override

View File

@ -66,7 +66,7 @@ public class ExprUtils
origin = null;
} else {
Chronology chronology = timeZone == null ? ISOChronology.getInstanceUTC() : ISOChronology.getInstance(timeZone);
final Object value = originArg.eval(bindings).value();
final Object value = originArg.eval(bindings).valueOrDefault();
if (value instanceof String && NullHandling.isNullOrEquivalent((String) value)) {
// We get a blank string here, when sql compatible null handling is enabled
// and expression contains empty string for for origin

View File

@ -124,11 +124,11 @@ public class TimestampFloorExprMacro implements ExprMacroTable.ExprMacro
}
@Override
public <T> ExprVectorProcessor<T> buildVectorized(VectorInputBindingInspector inspector)
public <T> ExprVectorProcessor<T> asVectorProcessor(VectorInputBindingInspector inspector)
{
ExprVectorProcessor<?> processor;
processor = new LongOutLongInFunctionVectorValueProcessor(
CastToTypeVectorProcessor.cast(args.get(0).buildVectorized(inspector), ExpressionType.LONG),
CastToTypeVectorProcessor.cast(args.get(0).asVectorProcessor(inspector), ExpressionType.LONG),
inspector.getMaxVectorSize()
)
{

View File

@ -119,11 +119,11 @@ public class TimestampShiftExprMacro implements ExprMacroTable.ExprMacro
}
@Override
public <T> ExprVectorProcessor<T> buildVectorized(VectorInputBindingInspector inspector)
public <T> ExprVectorProcessor<T> asVectorProcessor(VectorInputBindingInspector inspector)
{
ExprVectorProcessor<?> processor;
processor = new LongOutLongInFunctionVectorValueProcessor(
CastToTypeVectorProcessor.cast(args.get(0).buildVectorized(inspector), ExpressionType.LONG),
CastToTypeVectorProcessor.cast(args.get(0).asVectorProcessor(inspector), ExpressionType.LONG),
inspector.getMaxVectorSize()
)
{

View File

@ -110,7 +110,7 @@ public class ExpressionSelectors
{
// No need for null check on getObject() since baseSelector impls will never return null.
ExprEval eval = baseSelector.getObject();
return eval.value();
return eval.valueOrDefault();
}
@Override
@ -196,14 +196,7 @@ public class ExpressionSelectors
Expr expression
)
{
return makeExprEvalSelector(columnSelectorFactory, ExpressionPlanner.plan(columnSelectorFactory, expression));
}
public static ColumnValueSelector<ExprEval> makeExprEvalSelector(
ColumnSelectorFactory columnSelectorFactory,
ExpressionPlan plan
)
{
ExpressionPlan plan = ExpressionPlanner.plan(columnSelectorFactory, expression);
final RowIdSupplier rowIdSupplier = columnSelectorFactory.getRowIdSupplier();
if (plan.is(ExpressionPlan.Trait.SINGLE_INPUT_SCALAR)) {
@ -548,6 +541,6 @@ public class ExpressionSelectors
}
return Arrays.stream(asArray).collect(Collectors.toList());
}
return eval.value();
return eval.valueOrDefault();
}
}

View File

@ -79,11 +79,11 @@ public class ExpressionVectorSelectors
if (plan.isConstant()) {
return ConstantVectorSelectors.vectorValueSelector(
factory.getReadableVectorInspector(),
(Number) plan.getExpression().eval(InputBindings.nilBindings()).value()
(Number) plan.getExpression().eval(InputBindings.nilBindings()).valueOrDefault()
);
}
final Expr.VectorInputBinding bindings = createVectorBindings(plan.getAnalysis(), factory);
final ExprVectorProcessor<?> processor = plan.getExpression().buildVectorized(bindings);
final ExprVectorProcessor<?> processor = plan.getExpression().asVectorProcessor(bindings);
return new ExpressionVectorValueSelector(processor, bindings);
}
@ -98,12 +98,12 @@ public class ExpressionVectorSelectors
if (plan.isConstant()) {
return ConstantVectorSelectors.vectorObjectSelector(
factory.getReadableVectorInspector(),
plan.getExpression().eval(InputBindings.nilBindings()).value()
plan.getExpression().eval(InputBindings.nilBindings()).valueOrDefault()
);
}
final Expr.VectorInputBinding bindings = createVectorBindings(plan.getAnalysis(), factory);
final ExprVectorProcessor<?> processor = plan.getExpression().buildVectorized(bindings);
final ExprVectorProcessor<?> processor = plan.getExpression().asVectorProcessor(bindings);
return new ExpressionVectorObjectSelector(processor, bindings);
}

View File

@ -507,7 +507,7 @@ public class NestedFieldVirtualColumn implements VirtualColumn
nullVector = new boolean[objectSelector.getMaxVectorSize()];
}
longVector[i] = 0L;
nullVector[i] = true;
nullVector[i] = NullHandling.sqlCompatible();
} else {
Long l;
if (v instanceof Number) {
@ -525,7 +525,7 @@ public class NestedFieldVirtualColumn implements VirtualColumn
nullVector = new boolean[objectSelector.getMaxVectorSize()];
}
longVector[i] = 0L;
nullVector[i] = true;
nullVector[i] = NullHandling.sqlCompatible();
}
}
}
@ -570,7 +570,7 @@ public class NestedFieldVirtualColumn implements VirtualColumn
nullVector = new boolean[objectSelector.getMaxVectorSize()];
}
doubleVector[i] = 0.0;
nullVector[i] = true;
nullVector[i] = NullHandling.sqlCompatible();
} else {
Double d;
if (v instanceof Number) {
@ -588,7 +588,7 @@ public class NestedFieldVirtualColumn implements VirtualColumn
nullVector = new boolean[objectSelector.getMaxVectorSize()];
}
doubleVector[i] = 0.0;
nullVector[i] = true;
nullVector[i] = NullHandling.sqlCompatible();
}
}
}

View File

@ -62,7 +62,7 @@ public class SingleStringInputDeferredEvaluationExpressionDimensionVectorSelecto
}
this.selector = selector;
this.inputBinding = new StringLookupVectorInputBindings();
this.stringProcessor = expression.buildVectorized(inputBinding);
this.stringProcessor = expression.asVectorProcessor(inputBinding);
}
@Override

View File

@ -247,18 +247,18 @@ public class EvalTest extends InitializedNullHandlingTest
// test casting arrays to scalars
assertEquals(1L, ExprEval.ofLongArray(new Long[]{1L}).castTo(ExpressionType.LONG).value());
assertEquals(NullHandling.defaultLongValue(), ExprEval.ofLongArray(new Long[]{null}).castTo(ExpressionType.LONG).value());
assertEquals(null, ExprEval.ofLongArray(new Long[]{null}).castTo(ExpressionType.LONG).value());
assertEquals(1.0, ExprEval.ofLongArray(new Long[]{1L}).castTo(ExpressionType.DOUBLE).asDouble(), 0.0);
assertEquals("1", ExprEval.ofLongArray(new Long[]{1L}).castTo(ExpressionType.STRING).value());
assertEquals(1.1, ExprEval.ofDoubleArray(new Double[]{1.1}).castTo(ExpressionType.DOUBLE).asDouble(), 0.0);
assertEquals(NullHandling.defaultDoubleValue(), ExprEval.ofDoubleArray(new Double[]{null}).castTo(ExpressionType.DOUBLE).value());
assertEquals(null, ExprEval.ofDoubleArray(new Double[]{null}).castTo(ExpressionType.DOUBLE).value());
assertEquals(1L, ExprEval.ofDoubleArray(new Double[]{1.1}).castTo(ExpressionType.LONG).value());
assertEquals("1.1", ExprEval.ofDoubleArray(new Double[]{1.1}).castTo(ExpressionType.STRING).value());
assertEquals("foo", ExprEval.ofStringArray(new String[]{"foo"}).castTo(ExpressionType.STRING).value());
assertEquals(NullHandling.defaultLongValue(), ExprEval.ofStringArray(new String[]{"foo"}).castTo(ExpressionType.LONG).value());
assertEquals(NullHandling.defaultDoubleValue(), ExprEval.ofStringArray(new String[]{"foo"}).castTo(ExpressionType.DOUBLE).value());
assertEquals(null, ExprEval.ofStringArray(new String[]{"foo"}).castTo(ExpressionType.LONG).value());
assertEquals(null, ExprEval.ofStringArray(new String[]{"foo"}).castTo(ExpressionType.DOUBLE).value());
assertEquals("1", ExprEval.ofStringArray(new String[]{"1"}).castTo(ExpressionType.STRING).value());
assertEquals(1L, ExprEval.ofStringArray(new String[]{"1"}).castTo(ExpressionType.LONG).value());
assertEquals(1.0, ExprEval.ofStringArray(new String[]{"1"}).castTo(ExpressionType.DOUBLE).value());
@ -518,17 +518,18 @@ public class EvalTest extends InitializedNullHandlingTest
assertEquals(1L, eval("null || 1", bindings).value());
assertEquals(1L, eval("1 || null", bindings).value());
assertEquals(NullHandling.defaultLongValue(), eval("null || 0", bindings).value());
assertEquals(NullHandling.defaultLongValue(), eval("0 || null", bindings).value());
// null/null is evaluated as string typed
assertEquals(NullHandling.defaultLongValue(), eval("null || null", bindings).value());
// in sql incompatible mode, null is false, so we return 0
assertEquals(NullHandling.defaultLongValue(), eval("null || 0", bindings).valueOrDefault());
assertEquals(NullHandling.defaultLongValue(), eval("0 || null", bindings).valueOrDefault());
assertEquals(NullHandling.defaultLongValue(), eval("null || null", bindings).valueOrDefault());
assertEquals(NullHandling.defaultLongValue(), eval("null && 1", bindings).value());
assertEquals(NullHandling.defaultLongValue(), eval("1 && null", bindings).value());
// in sql incompatible mode, null is false, so we return 0
assertEquals(NullHandling.defaultLongValue(), eval("null && 1", bindings).valueOrDefault());
assertEquals(NullHandling.defaultLongValue(), eval("1 && null", bindings).valueOrDefault());
assertEquals(NullHandling.defaultLongValue(), eval("null && null", bindings).valueOrDefault());
// if either side is false, output is false in both modes
assertEquals(0L, eval("null && 0", bindings).value());
assertEquals(0L, eval("0 && null", bindings).value());
// null/null is evaluated as string typed
assertEquals(NullHandling.defaultLongValue(), eval("null && null", bindings).value());
}
finally {
// reset
@ -707,6 +708,26 @@ public class EvalTest extends InitializedNullHandlingTest
}
}
@Test
public void testValueOrDefault()
{
ExprEval<?> longNull = ExprEval.ofLong(null);
ExprEval<?> doubleNull = ExprEval.ofDouble(null);
Assert.assertEquals(NullHandling.sqlCompatible(), longNull.isNumericNull());
Assert.assertEquals(NullHandling.sqlCompatible(), doubleNull.isNumericNull());
Assert.assertEquals(NullHandling.defaultLongValue(), longNull.valueOrDefault());
Assert.assertEquals(NullHandling.defaultDoubleValue(), doubleNull.valueOrDefault());
if (NullHandling.replaceWithDefault()) {
Assert.assertEquals(0L, longNull.asLong());
Assert.assertEquals(0, longNull.asInt());
Assert.assertEquals(0.0, longNull.asDouble(), 0.0);
Assert.assertEquals(0L, doubleNull.asLong());
Assert.assertEquals(0, doubleNull.asInt());
Assert.assertEquals(0.0, doubleNull.asDouble(), 0.0);
}
}
@Test
public void testEvalOfType()
{
@ -831,7 +852,7 @@ public class EvalTest extends InitializedNullHandlingTest
eval = ExprEval.ofType(ExpressionType.LONG_ARRAY, new Object[] {1L, 2L, null, 3L});
Assert.assertEquals(ExpressionType.LONG_ARRAY, eval.type());
Assert.assertArrayEquals(new Object[] {1L, 2L, NullHandling.defaultLongValue(), 3L}, (Object[]) eval.value());
Assert.assertArrayEquals(new Object[] {1L, 2L, null, 3L}, (Object[]) eval.value());
// arrays might have to fall back to using 'bestEffortOf', but will cast it to the expected output type
eval = ExprEval.ofType(ExpressionType.LONG_ARRAY, new Object[] {"1", "2", "3"});
@ -844,7 +865,7 @@ public class EvalTest extends InitializedNullHandlingTest
eval = ExprEval.ofType(ExpressionType.LONG_ARRAY, new Object[] {"1", "2", "wat", "3"});
Assert.assertEquals(ExpressionType.LONG_ARRAY, eval.type());
Assert.assertArrayEquals(new Object[] {1L, 2L, NullHandling.defaultLongValue(), 3L}, (Object[]) eval.value());
Assert.assertArrayEquals(new Object[] {1L, 2L, null, 3L}, (Object[]) eval.value());
eval = ExprEval.ofType(ExpressionType.LONG_ARRAY, new Object[] {1.0, 2.0, 3.0});
Assert.assertEquals(ExpressionType.LONG_ARRAY, eval.type());
@ -856,7 +877,7 @@ public class EvalTest extends InitializedNullHandlingTest
eval = ExprEval.ofType(ExpressionType.LONG_ARRAY, new Object[] {1.0, 2.0, null, 3.0});
Assert.assertEquals(ExpressionType.LONG_ARRAY, eval.type());
Assert.assertArrayEquals(new Object[] {1L, 2L, NullHandling.defaultLongValue(), 3L}, (Object[]) eval.value());
Assert.assertArrayEquals(new Object[] {1L, 2L, null, 3L}, (Object[]) eval.value());
eval = ExprEval.ofType(ExpressionType.LONG_ARRAY, new Object[] {1.0, 2L, "3", true, false});
Assert.assertEquals(ExpressionType.LONG_ARRAY, eval.type());
@ -885,7 +906,7 @@ public class EvalTest extends InitializedNullHandlingTest
eval = ExprEval.ofType(ExpressionType.DOUBLE_ARRAY, new Object[] {"1", "2", "wat", "3"});
Assert.assertEquals(ExpressionType.DOUBLE_ARRAY, eval.type());
Assert.assertArrayEquals(new Object[] {1.0, 2.0, NullHandling.defaultDoubleValue(), 3.0}, (Object[]) eval.value());
Assert.assertArrayEquals(new Object[] {1.0, 2.0, null, 3.0}, (Object[]) eval.value());
eval = ExprEval.ofType(ExpressionType.DOUBLE_ARRAY, new Object[] {1L, 2L, 3L});
Assert.assertEquals(ExpressionType.DOUBLE_ARRAY, eval.type());
@ -897,7 +918,7 @@ public class EvalTest extends InitializedNullHandlingTest
eval = ExprEval.ofType(ExpressionType.DOUBLE_ARRAY, new Object[] {1L, 2L, null, 3L});
Assert.assertEquals(ExpressionType.DOUBLE_ARRAY, eval.type());
Assert.assertArrayEquals(new Object[] {1.0, 2.0, NullHandling.defaultDoubleValue(), 3.0}, (Object[]) eval.value());
Assert.assertArrayEquals(new Object[] {1.0, 2.0, null, 3.0}, (Object[]) eval.value());
eval = ExprEval.ofType(ExpressionType.DOUBLE_ARRAY, new Object[] {1.0, 2L, "3", true, false});
Assert.assertEquals(ExpressionType.DOUBLE_ARRAY, eval.type());
@ -934,7 +955,7 @@ public class EvalTest extends InitializedNullHandlingTest
ExpressionType nestedLongArray = ExpressionTypeFactory.getInstance().ofArray(ExpressionType.LONG_ARRAY);
final Object[] expectedLongArray = new Object[]{
new Object[] {1L, 2L, 3L},
new Object[] {5L, NullHandling.defaultLongValue(), 9L},
new Object[] {5L, null, 9L},
null,
new Object[] {2L, 4L, 6L}
};
@ -979,7 +1000,7 @@ public class EvalTest extends InitializedNullHandlingTest
ExpressionType nestedDoubleArray = ExpressionTypeFactory.getInstance().ofArray(ExpressionType.DOUBLE_ARRAY);
final Object[] expectedDoubleArray = new Object[]{
new Object[] {1.1, 2.2, 3.3},
new Object[] {5.5, NullHandling.defaultDoubleValue(), 9.9},
new Object[] {5.5, null, 9.9},
null,
new Object[] {2.2, 4.4, 6.6}
};
@ -1109,7 +1130,7 @@ public class EvalTest extends InitializedNullHandlingTest
eval = ExprEval.bestEffortOf(new Object[] {null, 1.0, 2.0, 3.0});
Assert.assertEquals(ExpressionType.DOUBLE_ARRAY, eval.type());
Assert.assertArrayEquals(new Object[] {NullHandling.defaultDoubleValue(), 1.0, 2.0, 3.0}, (Object[]) eval.value());
Assert.assertArrayEquals(new Object[] {null, 1.0, 2.0, 3.0}, (Object[]) eval.value());
eval = ExprEval.bestEffortOf(new Double[] {1.0, 2.0, 3.0});
Assert.assertEquals(ExpressionType.DOUBLE_ARRAY, eval.type());

View File

@ -21,7 +21,6 @@ package org.apache.druid.math.expr;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import org.apache.druid.common.config.NullHandling;
import org.apache.druid.java.util.common.ISE;
import org.apache.druid.java.util.common.NonnullPair;
import org.apache.druid.java.util.common.StringUtils;
@ -403,11 +402,11 @@ public class ExprEvalTest extends InitializedNullHandlingTest
{
ExprEval someStringArray = ExprEval.ofStringArray(new String[]{"1", "2", "foo", null, "3.3"});
Assert.assertArrayEquals(
new Object[]{1L, 2L, NullHandling.defaultLongValue(), NullHandling.defaultLongValue(), 3L},
new Object[]{1L, 2L, null, null, 3L},
someStringArray.castTo(ExpressionType.LONG_ARRAY).asArray()
);
Assert.assertArrayEquals(
new Object[]{1.0, 2.0, NullHandling.defaultDoubleValue(), NullHandling.defaultDoubleValue(), 3.3},
new Object[]{1.0, 2.0, null, null, 3.3},
someStringArray.castTo(ExpressionType.DOUBLE_ARRAY).asArray()
);
}

View File

@ -139,7 +139,7 @@ public class FunctionTest extends InitializedNullHandlingTest
public void testStrlen()
{
assertExpr("strlen(x)", 3L);
assertExpr("strlen(nonexistent)", NullHandling.defaultLongValue());
assertExpr("strlen(nonexistent)", null);
}
@Test
@ -298,7 +298,7 @@ public class FunctionTest extends InitializedNullHandlingTest
public void testArrayAppend()
{
assertArrayExpr("array_append([1, 2, 3], 4)", new Long[]{1L, 2L, 3L, 4L});
assertArrayExpr("array_append([1, 2, 3], 'bar')", new Long[]{1L, 2L, 3L, NullHandling.defaultLongValue()});
assertArrayExpr("array_append([1, 2, 3], 'bar')", new Long[]{1L, 2L, 3L, null});
assertArrayExpr("array_append([], 1)", new String[]{"1"});
assertArrayExpr("array_append(<LONG>[], 1)", new Long[]{1L});
}
@ -317,11 +317,11 @@ public class FunctionTest extends InitializedNullHandlingTest
public void testArraySetAdd()
{
assertArrayExpr("array_set_add([1, 2, 3], 4)", new Long[]{1L, 2L, 3L, 4L});
assertArrayExpr("array_set_add([1, 2, 3], 'bar')", new Long[]{NullHandling.defaultLongValue(), 1L, 2L, 3L});
assertArrayExpr("array_set_add([1, 2, 3], 'bar')", new Long[]{null, 1L, 2L, 3L});
assertArrayExpr("array_set_add([1, 2, 2], 1)", new Long[]{1L, 2L});
assertArrayExpr("array_set_add([], 1)", new String[]{"1"});
assertArrayExpr("array_set_add(<LONG>[], 1)", new Long[]{1L});
assertArrayExpr("array_set_add(<LONG>[], null)", new Long[]{NullHandling.defaultLongValue()});
assertArrayExpr("array_set_add(<LONG>[], null)", new Long[]{null});
}
@Test
@ -392,7 +392,7 @@ public class FunctionTest extends InitializedNullHandlingTest
public void testArrayPrepend()
{
assertArrayExpr("array_prepend(4, [1, 2, 3])", new Long[]{4L, 1L, 2L, 3L});
assertArrayExpr("array_prepend('bar', [1, 2, 3])", new Long[]{NullHandling.defaultLongValue(), 1L, 2L, 3L});
assertArrayExpr("array_prepend('bar', [1, 2, 3])", new Long[]{null, 1L, 2L, 3L});
assertArrayExpr("array_prepend(1, [])", new String[]{"1"});
assertArrayExpr("array_prepend(1, <LONG>[])", new Long[]{1L});
assertArrayExpr("array_prepend(1, <DOUBLE>[])", new Double[]{1.0});
@ -797,10 +797,10 @@ public class FunctionTest extends InitializedNullHandlingTest
// happy path maths
assertExpr("safe_divide(3, 1)", 3L);
assertExpr("safe_divide(4.5, 2)", 2.25);
assertExpr("safe_divide(3, 0)", NullHandling.defaultLongValue());
assertExpr("safe_divide(1, 0.0)", NullHandling.defaultDoubleValue());
assertExpr("safe_divide(3, 0)", null);
assertExpr("safe_divide(1, 0.0)", null);
// NaN and Infinity cases
assertExpr("safe_divide(NaN, 0.0)", NullHandling.defaultDoubleValue());
assertExpr("safe_divide(NaN, 0.0)", null);
assertExpr("safe_divide(0, NaN)", 0.0);
assertExpr("safe_divide(0, POSITIVE_INFINITY)", NullHandling.defaultLongValue());
assertExpr("safe_divide(POSITIVE_INFINITY,0)", NullHandling.defaultLongValue());

View File

@ -45,7 +45,7 @@ import java.util.function.Supplier;
* randomize inputs to various vector expressions and make sure the results match nonvectorized expressions
*
* this is not a replacement for correctness tests, but will ensure that vectorized and non-vectorized expression
* evaluation is at least self consistent...
* evaluation is at least self-consistent...
*/
public class VectorExprSanityTest extends InitializedNullHandlingTest
{
@ -302,11 +302,12 @@ public class VectorExprSanityTest extends InitializedNullHandlingTest
{
Assert.assertTrue(StringUtils.format("Cannot vectorize %s", expr), parsed.canVectorize(bindings.rhs));
ExpressionType outputType = parsed.getOutputType(bindings.rhs);
ExprEvalVector<?> vectorEval = parsed.buildVectorized(bindings.rhs).evalVector(bindings.rhs);
ExprEvalVector<?> vectorEval = parsed.asVectorProcessor(bindings.rhs).evalVector(bindings.rhs);
// 'null' expressions can have an output type of null, but still evaluate in default mode, so skip type checks
if (outputType != null) {
Assert.assertEquals(expr, outputType, vectorEval.getType());
}
final Object[] vectorVals = vectorEval.getObjectVector();
for (int i = 0; i < VECTOR_SIZE; i++) {
ExprEval<?> eval = parsed.eval(bindings.lhs[i]);
// 'null' expressions can have an output type of null, but still evaluate in default mode, so skip type checks
@ -315,8 +316,8 @@ public class VectorExprSanityTest extends InitializedNullHandlingTest
}
Assert.assertEquals(
StringUtils.format("Values do not match for row %s for expression %s", i, expr),
eval.value(),
vectorEval.get(i)
eval.valueOrDefault(),
vectorVals[i]
);
}
}

View File

@ -193,8 +193,7 @@ public class ExprMacroTest
@Test
public void testIPv4AddressParse()
{
Long nullLong = NullHandling.replaceWithDefault() ? NullHandling.ZERO_LONG : null;
assertExpr("ipv4_parse(x)", nullLong);
assertExpr("ipv4_parse(x)", null);
assertExpr("ipv4_parse(ipv4_string)", IPV4_LONG);
assertExpr("ipv4_parse(ipv4_long)", IPV4_LONG);
assertExpr("ipv4_parse(ipv4_stringify(ipv4_long))", IPV4_LONG);

View File

@ -19,7 +19,6 @@
package org.apache.druid.query.expression;
import org.apache.druid.common.config.NullHandling;
import org.apache.druid.math.expr.Expr;
import org.apache.druid.math.expr.ExprEval;
import org.apache.druid.math.expr.InputBindings;
@ -33,7 +32,6 @@ public class IPv4AddressParseExprMacroTest extends MacroTestBase
{
private static final Expr VALID = ExprEval.of("192.168.0.1").toExpr();
private static final long EXPECTED = 3232235521L;
private static final Long NULL = NullHandling.replaceWithDefault() ? NullHandling.ZERO_LONG : null;
public IPv4AddressParseExprMacroTest()
{
@ -57,45 +55,45 @@ public class IPv4AddressParseExprMacroTest extends MacroTestBase
}
@Test
public void testNullStringArg()
public void testnullStringArg()
{
Expr nullString = ExprEval.of(null).toExpr();
Assert.assertSame(NULL, eval(nullString));
Assert.assertNull(eval(nullString));
}
@Test
public void testNullLongArg()
public void testnullLongArg()
{
Expr nullLong = ExprEval.ofLong(null).toExpr();
Assert.assertEquals(NULL, eval(nullLong));
Assert.assertNull(eval(nullLong));
}
@Test
public void testInvalidArgType()
{
Expr longArray = ExprEval.ofLongArray(new Long[]{1L, 2L}).toExpr();
Assert.assertEquals(NULL, eval(longArray));
Assert.assertNull(eval(longArray));
}
@Test
public void testInvalidStringArgNotIPAddress()
{
Expr notIpAddress = ExprEval.of("druid.apache.org").toExpr();
Assert.assertEquals(NULL, eval(notIpAddress));
Assert.assertNull(eval(notIpAddress));
}
@Test
public void testInvalidStringArgIPv6Compatible()
{
Expr ipv6Compatible = ExprEval.of("::192.168.0.1").toExpr();
Assert.assertEquals(NULL, eval(ipv6Compatible));
Assert.assertNull(eval(ipv6Compatible));
}
@Test
public void testValidStringArgIPv6Mapped()
{
Expr ipv6Mapped = ExprEval.of("::ffff:192.168.0.1").toExpr();
Assert.assertEquals(NULL, eval(ipv6Mapped));
Assert.assertNull(eval(ipv6Mapped));
}
@Test
@ -108,14 +106,14 @@ public class IPv4AddressParseExprMacroTest extends MacroTestBase
public void testValidStringArgUnsignedInt()
{
Expr unsignedInt = ExprEval.of("3232235521").toExpr();
Assert.assertEquals(NULL, eval(unsignedInt));
Assert.assertNull(eval(unsignedInt));
}
@Test
public void testInvalidLongArgTooLow()
{
Expr tooLow = ExprEval.ofLong(-1L).toExpr();
Assert.assertEquals(NULL, eval(tooLow));
Assert.assertNull(eval(tooLow));
}
@Test
@ -138,7 +136,7 @@ public class IPv4AddressParseExprMacroTest extends MacroTestBase
public void testInvalidLongArgTooHigh()
{
Expr tooHigh = ExprEval.ofLong(0x1_00_00_00_00L).toExpr();
Assert.assertEquals(NULL, eval(tooHigh));
Assert.assertNull(eval(tooHigh));
}
@Test

View File

@ -24,7 +24,6 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import org.apache.druid.common.config.NullHandling;
import org.apache.druid.jackson.DefaultObjectMapper;
import org.apache.druid.java.util.common.Pair;
import org.apache.druid.math.expr.Expr;
@ -173,7 +172,7 @@ public class NestedDataExpressionsTest extends InitializedNullHandlingTest
expr = Parser.parse("json_value(nester, '$.y.a', 'LONG')", MACRO_TABLE);
eval = expr.eval(inputBindings);
Assert.assertEquals(NullHandling.defaultLongValue(), eval.value());
Assert.assertNull(eval.value());
Assert.assertEquals(ExpressionType.LONG, eval.type());
expr = Parser.parse("json_value(nester, '$.y.a.b.c[12]')", MACRO_TABLE);

View File

@ -191,7 +191,7 @@ public class DruidRexExecutor implements RexExecutor
// column selector anyway
literal = constExp;
} else {
literal = rexBuilder.makeLiteral(exprResult.value(), constExp.getType(), true);
literal = rexBuilder.makeLiteral(exprResult.valueOrDefault(), constExp.getType(), true);
}
}

View File

@ -118,7 +118,7 @@ public class DruidUnnestDatasourceRel extends DruidRel<DruidUnnestDatasourceRel>
// with the input column being called "inline" in the native query
UnnestDataSource dataSource = UnnestDataSource.create(
InlineDataSource.fromIterable(
Collections.singletonList(new Object[]{eval.value()}),
Collections.singletonList(new Object[]{eval.valueOrDefault()}),
RowSignature.builder().add("inline", ExpressionType.toColumnType(eval.type())).build()
),
"inline",

View File

@ -707,7 +707,7 @@ public class ExpressionsTest extends ExpressionTestBase
DruidExpression.ofColumn(ColumnType.STRING, "hexstr")
)
),
NullHandling.sqlCompatible() ? null : 0L
null
);
}

View File

@ -21,7 +21,6 @@ package org.apache.druid.sql.calcite.expression;
import com.google.common.collect.ImmutableMap;
import org.apache.calcite.rex.RexNode;
import org.apache.druid.common.config.NullHandling;
import org.apache.druid.math.expr.ExpressionValidationException;
import org.apache.druid.segment.column.ColumnType;
import org.apache.druid.segment.column.RowSignature;
@ -39,7 +38,6 @@ public class IPv4AddressParseExpressionTest extends ExpressionTestBase
private static final String VALID = "192.168.0.1";
private static final long EXPECTED = 3232235521L;
private static final Object IGNORE_EXPECTED_RESULT = null;
private static final Long NULL = NullHandling.replaceWithDefault() ? NullHandling.ZERO_LONG : null;
private static final String VAR = "f";
private static final RowSignature ROW_SIGNATURE = RowSignature.builder().add(VAR, ColumnType.FLOAT).build();
@ -88,7 +86,7 @@ public class IPv4AddressParseExpressionTest extends ExpressionTestBase
testExpression(
testHelper.getConstantNull(),
buildExpectedExpression((String) null),
NULL
null
);
}
@ -99,7 +97,7 @@ public class IPv4AddressParseExpressionTest extends ExpressionTestBase
testExpression(
testHelper.makeInputRef(variableNameWithInvalidType),
buildExpectedExpression(testHelper.makeVariable(variableNameWithInvalidType)),
NULL
null
);
}
@ -110,7 +108,7 @@ public class IPv4AddressParseExpressionTest extends ExpressionTestBase
testExpression(
testHelper.makeLiteral(notIpAddress),
buildExpectedExpression(notIpAddress),
NULL
null
);
}
@ -121,7 +119,7 @@ public class IPv4AddressParseExpressionTest extends ExpressionTestBase
testExpression(
testHelper.makeLiteral(ipv6Compatible),
buildExpectedExpression(ipv6Compatible),
NULL
null
);
}
@ -132,7 +130,7 @@ public class IPv4AddressParseExpressionTest extends ExpressionTestBase
testExpression(
testHelper.makeLiteral(ipv6Mapped),
buildExpectedExpression(ipv6Mapped),
NULL
null
);
}
@ -153,7 +151,7 @@ public class IPv4AddressParseExpressionTest extends ExpressionTestBase
testExpression(
testHelper.makeLiteral(unsignedInt),
buildExpectedExpression(unsignedInt),
NULL
null
);
}
@ -164,7 +162,7 @@ public class IPv4AddressParseExpressionTest extends ExpressionTestBase
testExpression(
testHelper.makeLiteral(tooLow),
buildExpectedExpression(tooLow),
NULL
null
);
}
@ -207,7 +205,7 @@ public class IPv4AddressParseExpressionTest extends ExpressionTestBase
testExpression(
testHelper.makeLiteral(tooHigh),
buildExpectedExpression(tooHigh),
NULL
null
);
}