void SubstraitToVeloxPlanConverter::setFilterInfo()

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);
}