TypePtr VeloxSubstraitSignature::fromSubstraitSignature()

in cpp/velox/substrait/VeloxSubstraitSignature.cc [75:172]


TypePtr VeloxSubstraitSignature::fromSubstraitSignature(const std::string& signature) {
  if (signature == "bool") {
    return BOOLEAN();
  }

  if (signature == "i8") {
    return TINYINT();
  }

  if (signature == "i16") {
    return SMALLINT();
  }

  if (signature == "i32") {
    return INTEGER();
  }

  if (signature == "i64") {
    return BIGINT();
  }

  if (signature == "fp32") {
    return REAL();
  }

  if (signature == "fp64") {
    return DOUBLE();
  }

  if (signature == "str") {
    return VARCHAR();
  }

  if (signature == "vbin") {
    return VARBINARY();
  }

  if (signature == "ts") {
    return TIMESTAMP();
  }

  if (signature == "date") {
    return DATE();
  }

  auto startWith = [](const std::string& str, const std::string& prefix) {
    return str.size() >= prefix.size() && str.substr(0, prefix.size()) == prefix;
  };

  if (startWith(signature, "dec")) {
    // Decimal type name is in the format of dec<precision,scale>.
    auto precisionStart = signature.find_first_of('<');
    auto tokenIndex = signature.find_first_of(',');
    auto scaleEnd = signature.find_first_of('>');
    auto precision = stoi(signature.substr(precisionStart + 1, (tokenIndex - precisionStart - 1)));
    auto scale = stoi(signature.substr(tokenIndex + 1, (scaleEnd - tokenIndex - 1)));
    return DECIMAL(precision, scale);
  }

  if (startWith(signature, "struct")) {
    // Struct type name is in the format of struct<T1,T2,...,Tn>.
    auto structStart = signature.find_first_of('<');
    auto structEnd = signature.find_last_of('>');
    VELOX_CHECK(
        structEnd - structStart > 1, "Native validation failed due to: more information is needed to create RowType");
    std::string childrenTypes = signature.substr(structStart + 1, structEnd - structStart - 1);

    // Split the types with delimiter.
    std::string delimiter = ",";
    std::size_t pos;
    std::vector<TypePtr> types;
    std::vector<std::string> names;
    while ((pos = childrenTypes.find(delimiter)) != std::string::npos) {
      auto typeStr = childrenTypes.substr(0, pos);
      std::size_t endPos = pos;
      if (startWith(typeStr, "dec") || startWith(typeStr, "struct")) {
        endPos = childrenTypes.find(">") + 1;
        if (endPos > pos) {
          typeStr += childrenTypes.substr(pos, endPos - pos);
        } else {
          // For nested case, the end '>' could missing,
          // so the last position is treated as end.
          typeStr += childrenTypes.substr(pos);
          endPos = childrenTypes.size();
        }
      }
      types.emplace_back(fromSubstraitSignature(typeStr));
      names.emplace_back("");
      childrenTypes.erase(0, endPos + delimiter.length());
    }
    if (childrenTypes.size() > 0 && !startWith(childrenTypes, ">")) {
      types.emplace_back(fromSubstraitSignature(childrenTypes));
      names.emplace_back("");
    }
    return std::make_shared<RowType>(std::move(names), std::move(types));
  }
  VELOX_UNSUPPORTED("Substrait type signature conversion to Velox type not supported for {}.", signature);
}