mirror of https://github.com/apache/druid.git
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:
parent
faf602108b
commit
6cf754b0e0
|
@ -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(
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -147,7 +147,7 @@ class IdentifierExpr implements Expr
|
|||
}
|
||||
|
||||
@Override
|
||||
public ExprVectorProcessor<?> buildVectorized(VectorInputBindingInspector inspector)
|
||||
public ExprVectorProcessor<?> asVectorProcessor(VectorInputBindingInspector inspector)
|
||||
{
|
||||
return VectorProcessors.identifier(inspector, binding);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
)
|
||||
{
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
)
|
||||
{
|
||||
|
|
|
@ -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()
|
||||
)
|
||||
{
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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()
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -707,7 +707,7 @@ public class ExpressionsTest extends ExpressionTestBase
|
|||
DruidExpression.ofColumn(ColumnType.STRING, "hexstr")
|
||||
)
|
||||
),
|
||||
NullHandling.sqlCompatible() ? null : 0L
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue