in cpp/velox/substrait/SubstraitToVeloxPlan.cc [1748:1823]
void SubstraitToVeloxPlanConverter::setFilterInfo(
const ::substrait::Expression_ScalarFunction& scalarFunction,
const std::vector<TypePtr>& inputTypeList,
std::vector<FilterInfo>& columnToFilterInfo,
bool reverse) {
auto nameSpec = SubstraitParser::findFunctionSpec(functionMap_, scalarFunction.function_reference());
auto functionName = SubstraitParser::getNameBeforeDelimiter(nameSpec);
// Extract the column index and column bound from the scalar function.
std::optional<uint32_t> colIdx;
std::optional<::substrait::Expression_Literal> substraitLit;
std::vector<std::string> typeCases;
for (const auto& param : scalarFunction.arguments()) {
auto typeCase = param.value().rex_type_case();
switch (typeCase) {
case ::substrait::Expression::RexTypeCase::kSelection:
typeCases.emplace_back("kSelection");
colIdx = SubstraitParser::parseReferenceSegment(param.value().selection().direct_reference());
break;
case ::substrait::Expression::RexTypeCase::kLiteral:
typeCases.emplace_back("kLiteral");
substraitLit = param.value().literal();
break;
default:
VELOX_NYI("Substrait conversion not supported for arg type '{}'", std::to_string(typeCase));
}
}
static const std::unordered_map<std::string, std::string> functionRevertMap = {
{sLt, sGt}, {sGt, sLt}, {sGte, sLte}, {sLte, sGte}};
// Handle the case where literal is before the variable in a binary function, e.g. "123 < q1".
if (typeCases.size() > 1 && (typeCases[0] == "kLiteral" && typeCases[1] == "kSelection")) {
auto x = functionRevertMap.find(functionName);
if (x != functionRevertMap.end()) {
// Change the function name: lt => gt, gt => lt, gte => lte, lte => gte.
functionName = x->second;
}
}
if (!colIdx.has_value()) {
VELOX_NYI("Column index is expected in subfield filters creation.");
}
// Set the extracted bound to the specific column.
uint32_t colIdxVal = colIdx.value();
std::optional<variant> val;
auto inputType = inputTypeList[colIdxVal];
switch (inputType->kind()) {
case TypeKind::TINYINT:
case TypeKind::SMALLINT:
case TypeKind::INTEGER:
case TypeKind::BIGINT:
case TypeKind::REAL:
case TypeKind::DOUBLE:
case TypeKind::BOOLEAN:
case TypeKind::VARCHAR:
case TypeKind::HUGEINT:
if (substraitLit) {
auto kind = inputType->kind();
val = VELOX_DYNAMIC_SCALAR_TYPE_DISPATCH(getVariantFromLiteral, kind, substraitLit.value());
}
break;
case TypeKind::ARRAY:
case TypeKind::MAP:
case TypeKind::ROW:
// Doing nothing here can let filter IsNotNull still work.
break;
default:
VELOX_NYI("Subfield filters creation not supported for input type '{}' in setFilterInfo", inputType->toString());
}
setColumnFilterInfo(functionName, val, columnToFilterInfo[colIdxVal], reverse);
}