in ql/src/java/org/apache/hadoop/hive/ql/exec/vector/VectorizationContext.java [3662:3877]
private VectorExpression getBetweenExpression(List<ExprNodeDesc> childExpr,
VectorExpressionDescriptor.Mode mode, TypeInfo returnType)
throws HiveException {
boolean hasDynamicValues = false;
// We don't currently support the BETWEEN ends being columns. They must be scalars.
if ((childExpr.get(2) instanceof ExprNodeDynamicValueDesc) &&
(childExpr.get(3) instanceof ExprNodeDynamicValueDesc)) {
hasDynamicValues = true;
if (mode == VectorExpressionDescriptor.Mode.PROJECTION) {
// Projection mode is not applicable.
return null;
}
} else if (!(childExpr.get(2) instanceof ExprNodeConstantDesc) ||
!(childExpr.get(3) instanceof ExprNodeConstantDesc)) {
return null;
}
boolean notKeywordPresent = (Boolean) ((ExprNodeConstantDesc) childExpr.get(0)).getValue();
ExprNodeDesc colExpr = childExpr.get(1);
// The children after not, might need a cast. Get common types for the two comparisons.
// Casting for 'between' is handled here as a special case, because the first child is for NOT and doesn't need
// cast
TypeInfo commonType = FunctionRegistry.getCommonClassForComparison(childExpr.get(1).getTypeInfo(),
childExpr.get(2).getTypeInfo());
if (commonType == null) {
// Can't vectorize
return null;
}
commonType = FunctionRegistry.getCommonClassForComparison(commonType, childExpr.get(3).getTypeInfo());
if (commonType == null) {
// Can't vectorize
return null;
}
List<ExprNodeDesc> castChildren = new ArrayList<>();
boolean wereCastUdfs = false;
Category commonTypeCategory = commonType.getCategory();
for (ExprNodeDesc desc: childExpr.subList(1, 4)) {
TypeInfo childTypeInfo = desc.getTypeInfo();
Category childCategory = childTypeInfo.getCategory();
if (childCategory != commonTypeCategory) {
return null;
}
final boolean isNeedsCast;
if (commonTypeCategory == Category.PRIMITIVE) {
// Do not to strict TypeInfo comparisons for DECIMAL -- just compare the category.
// Otherwise, we generate unnecessary casts.
isNeedsCast =
((PrimitiveTypeInfo) commonType).getPrimitiveCategory() !=
((PrimitiveTypeInfo) childTypeInfo).getPrimitiveCategory();
} else {
isNeedsCast = !commonType.equals(desc.getTypeInfo());
}
if (!isNeedsCast) {
castChildren.add(desc);
} else {
GenericUDF castUdf = getGenericUDFForCast(commonType);
ExprNodeGenericFuncDesc engfd = new ExprNodeGenericFuncDesc(commonType, castUdf,
Arrays.asList(new ExprNodeDesc[] { desc }));
castChildren.add(engfd);
wereCastUdfs = true;
}
}
String colType = commonType.getTypeName();
// prepare arguments for createVectorExpression
List<ExprNodeDesc> childrenAfterNot = evaluateCastOnConstants(castChildren);
// determine class
Class<?> cl = null;
if (isIntFamily(colType) && !notKeywordPresent) {
if (mode == VectorExpressionDescriptor.Mode.PROJECTION) {
cl = LongColumnBetween.class;
} else {
cl = (hasDynamicValues ?
FilterLongColumnBetweenDynamicValue.class :
FilterLongColumnBetween.class);
}
} else if (isIntFamily(colType) && notKeywordPresent) {
if (mode == VectorExpressionDescriptor.Mode.PROJECTION) {
cl = LongColumnNotBetween.class;
} else {
cl = FilterLongColumnNotBetween.class;
}
} else if (isFloatFamily(colType) && !notKeywordPresent) {
if (mode == VectorExpressionDescriptor.Mode.PROJECTION) {
cl = DoubleColumnBetween.class;
} else {
cl = (hasDynamicValues ?
FilterDoubleColumnBetweenDynamicValue.class :
FilterDoubleColumnBetween.class);
}
} else if (isFloatFamily(colType) && notKeywordPresent) {
if (mode == VectorExpressionDescriptor.Mode.PROJECTION) {
cl = DoubleColumnNotBetween.class;
} else {
cl = FilterDoubleColumnNotBetween.class;
}
} else if (colType.equals(serdeConstants.STRING_TYPE_NAME) && !notKeywordPresent) {
if (mode == VectorExpressionDescriptor.Mode.PROJECTION) {
cl = StringColumnBetween.class;
} else {
cl = (hasDynamicValues ?
FilterStringColumnBetweenDynamicValue.class :
FilterStringColumnBetween.class);
}
} else if (colType.equals(serdeConstants.STRING_TYPE_NAME) && notKeywordPresent) {
if (mode == VectorExpressionDescriptor.Mode.PROJECTION) {
cl = StringColumnNotBetween.class;
} else {
cl = FilterStringColumnNotBetween.class;
}
} else if (varcharTypePattern.matcher(colType).matches() && !notKeywordPresent) {
if (mode == VectorExpressionDescriptor.Mode.PROJECTION) {
cl = VarCharColumnBetween.class;
} else {
cl = (hasDynamicValues ?
FilterVarCharColumnBetweenDynamicValue.class :
FilterVarCharColumnBetween.class);
}
} else if (varcharTypePattern.matcher(colType).matches() && notKeywordPresent) {
if (mode == VectorExpressionDescriptor.Mode.PROJECTION) {
cl = VarCharColumnNotBetween.class;
} else {
cl = FilterVarCharColumnNotBetween.class;
}
} else if (charTypePattern.matcher(colType).matches() && !notKeywordPresent) {
if (mode == VectorExpressionDescriptor.Mode.PROJECTION) {
cl = CharColumnBetween.class;
} else {
cl = (hasDynamicValues ?
FilterCharColumnBetweenDynamicValue.class :
FilterCharColumnBetween.class);
}
} else if (charTypePattern.matcher(colType).matches() && notKeywordPresent) {
if (mode == VectorExpressionDescriptor.Mode.PROJECTION) {
cl = CharColumnNotBetween.class;
} else {
cl = FilterCharColumnNotBetween.class;
}
} else if (colType.equals(serdeConstants.TIMESTAMP_TYPE_NAME) && !notKeywordPresent) {
if (mode == VectorExpressionDescriptor.Mode.PROJECTION) {
cl = TimestampColumnBetween.class;
} else {
cl = (hasDynamicValues ?
FilterTimestampColumnBetweenDynamicValue.class :
FilterTimestampColumnBetween.class);
}
} else if (colType.equals(serdeConstants.TIMESTAMP_TYPE_NAME) && notKeywordPresent) {
if (mode == VectorExpressionDescriptor.Mode.PROJECTION) {
cl = TimestampColumnNotBetween.class;
} else {
cl = FilterTimestampColumnNotBetween.class;
}
} else if (isDecimalFamily(colType) && !notKeywordPresent) {
final boolean tryDecimal64 =
checkExprNodeDescForDecimal64(colExpr) && !wereCastUdfs && !hasDynamicValues;
if (tryDecimal64) {
VectorExpression decimal64VecExpr =
tryDecimal64Between(
mode, /* isNot */ false, colExpr, childrenAfterNot,
returnType);
if (decimal64VecExpr != null) {
return decimal64VecExpr;
}
}
if (mode == VectorExpressionDescriptor.Mode.PROJECTION) {
cl = DecimalColumnBetween.class;
} else {
cl = (hasDynamicValues ?
FilterDecimalColumnBetweenDynamicValue.class :
FilterDecimalColumnBetween.class);
}
} else if (isDecimalFamily(colType) && notKeywordPresent) {
final boolean tryDecimal64 =
checkExprNodeDescForDecimal64(colExpr) && !wereCastUdfs && !hasDynamicValues;
if (tryDecimal64) {
VectorExpression decimal64VecExpr =
tryDecimal64Between(
mode, /* isNot */ true, colExpr, childrenAfterNot, returnType);
if (decimal64VecExpr != null) {
return decimal64VecExpr;
}
}
if (mode == VectorExpressionDescriptor.Mode.PROJECTION) {
cl = DecimalColumnNotBetween.class;
} else {
cl = FilterDecimalColumnNotBetween.class;
}
} else if (isDateFamily(colType) && !notKeywordPresent) {
if (mode == VectorExpressionDescriptor.Mode.PROJECTION) {
cl = LongColumnBetween.class;
} else {
cl = (hasDynamicValues ?
FilterDateColumnBetweenDynamicValue.class :
FilterLongColumnBetween.class);
}
} else if (isDateFamily(colType) && notKeywordPresent) {
if (mode == VectorExpressionDescriptor.Mode.PROJECTION) {
cl = LongColumnNotBetween.class;
} else {
cl = FilterLongColumnNotBetween.class;
}
}
return createVectorExpression(
cl, childrenAfterNot, VectorExpressionDescriptor.Mode.PROJECTION, returnType, DataTypePhysicalVariation.NONE);
}