in cpp/src/arrow/ipc/metadata_internal.cc [241:426]
Status ConcreteTypeFromFlatbuffer(flatbuf::Type type, const void* type_data,
FieldVector children, std::shared_ptr<DataType>* out) {
switch (type) {
case flatbuf::Type::Type_NONE:
return Status::Invalid("Type metadata cannot be none");
case flatbuf::Type::Type_Null:
*out = null();
return Status::OK();
case flatbuf::Type::Type_Int:
return IntFromFlatbuffer(static_cast<const flatbuf::Int*>(type_data), out);
case flatbuf::Type::Type_FloatingPoint:
return FloatFromFlatbuffer(static_cast<const flatbuf::FloatingPoint*>(type_data),
out);
case flatbuf::Type::Type_Binary:
*out = binary();
return Status::OK();
case flatbuf::Type::Type_LargeBinary:
*out = large_binary();
return Status::OK();
case flatbuf::Type::Type_BinaryView:
*out = binary_view();
return Status::OK();
case flatbuf::Type::Type_FixedSizeBinary: {
auto fw_binary = static_cast<const flatbuf::FixedSizeBinary*>(type_data);
return FixedSizeBinaryType::Make(fw_binary->byteWidth()).Value(out);
}
case flatbuf::Type::Type_Utf8:
*out = utf8();
return Status::OK();
case flatbuf::Type::Type_LargeUtf8:
*out = large_utf8();
return Status::OK();
case flatbuf::Type::Type_Utf8View:
*out = utf8_view();
return Status::OK();
case flatbuf::Type::Type_Bool:
*out = boolean();
return Status::OK();
case flatbuf::Type::Type_Decimal: {
auto dec_type = static_cast<const flatbuf::Decimal*>(type_data);
switch (dec_type->bitWidth()) {
case 32:
return Decimal32Type::Make(dec_type->precision(), dec_type->scale()).Value(out);
case 64:
return Decimal64Type::Make(dec_type->precision(), dec_type->scale()).Value(out);
case 128:
return Decimal128Type::Make(dec_type->precision(), dec_type->scale())
.Value(out);
case 256:
return Decimal256Type::Make(dec_type->precision(), dec_type->scale())
.Value(out);
}
return Status::Invalid("Library only supports 32/64/128/256-bit decimal values");
}
case flatbuf::Type::Type_Date: {
auto date_type = static_cast<const flatbuf::Date*>(type_data);
if (date_type->unit() == flatbuf::DateUnit::DateUnit_DAY) {
*out = date32();
} else {
*out = date64();
}
return Status::OK();
}
case flatbuf::Type::Type_Time: {
auto time_type = static_cast<const flatbuf::Time*>(type_data);
TimeUnit::type unit = FromFlatbufferUnit(time_type->unit());
int32_t bit_width = time_type->bitWidth();
switch (unit) {
case TimeUnit::SECOND:
case TimeUnit::MILLI:
if (bit_width != 32) {
return Status::Invalid("Time is 32 bits for second/milli unit");
}
*out = time32(unit);
break;
default:
if (bit_width != 64) {
return Status::Invalid("Time is 64 bits for micro/nano unit");
}
*out = time64(unit);
break;
}
return Status::OK();
}
case flatbuf::Type::Type_Timestamp: {
auto ts_type = static_cast<const flatbuf::Timestamp*>(type_data);
TimeUnit::type unit = FromFlatbufferUnit(ts_type->unit());
*out = timestamp(unit, StringFromFlatbuffers(ts_type->timezone()));
return Status::OK();
}
case flatbuf::Type::Type_Duration: {
auto duration = static_cast<const flatbuf::Duration*>(type_data);
TimeUnit::type unit = FromFlatbufferUnit(duration->unit());
*out = arrow::duration(unit);
return Status::OK();
}
case flatbuf::Type::Type_Interval: {
auto i_type = static_cast<const flatbuf::Interval*>(type_data);
switch (i_type->unit()) {
case flatbuf::IntervalUnit::IntervalUnit_YEAR_MONTH: {
*out = month_interval();
return Status::OK();
}
case flatbuf::IntervalUnit::IntervalUnit_DAY_TIME: {
*out = day_time_interval();
return Status::OK();
}
case flatbuf::IntervalUnit::IntervalUnit_MONTH_DAY_NANO: {
*out = month_day_nano_interval();
return Status::OK();
}
}
return Status::NotImplemented("Unrecognized interval type.");
}
case flatbuf::Type::Type_List:
if (children.size() != 1) {
return Status::Invalid("List must have exactly 1 child field");
}
*out = std::make_shared<ListType>(children[0]);
return Status::OK();
case flatbuf::Type::Type_LargeList:
if (children.size() != 1) {
return Status::Invalid("LargeList must have exactly 1 child field");
}
*out = std::make_shared<LargeListType>(children[0]);
return Status::OK();
case flatbuf::Type::Type_ListView:
if (children.size() != 1) {
return Status::Invalid("ListView must have exactly 1 child field");
}
*out = std::make_shared<ListViewType>(children[0]);
return Status::OK();
case flatbuf::Type::Type_LargeListView:
if (children.size() != 1) {
return Status::Invalid("LargeListView must have exactly 1 child field");
}
*out = std::make_shared<LargeListViewType>(children[0]);
return Status::OK();
case flatbuf::Type::Type_Map:
if (children.size() != 1) {
return Status::Invalid("Map must have exactly 1 child field");
}
if (children[0]->nullable() || children[0]->type()->id() != Type::STRUCT ||
children[0]->type()->num_fields() != 2) {
return Status::Invalid("Map's key-item pairs must be non-nullable structs");
}
if (children[0]->type()->field(0)->nullable()) {
return Status::Invalid("Map's keys must be non-nullable");
} else {
auto map = static_cast<const flatbuf::Map*>(type_data);
*out = std::make_shared<MapType>(children[0]->type()->field(0)->WithName("key"),
children[0]->type()->field(1)->WithName("value"),
map->keysSorted());
}
return Status::OK();
case flatbuf::Type::Type_FixedSizeList:
if (children.size() != 1) {
return Status::Invalid("FixedSizeList must have exactly 1 child field");
} else {
auto fs_list = static_cast<const flatbuf::FixedSizeList*>(type_data);
*out = std::make_shared<FixedSizeListType>(children[0], fs_list->listSize());
}
return Status::OK();
case flatbuf::Type::Type_Struct_:
*out = std::make_shared<StructType>(children);
return Status::OK();
case flatbuf::Type::Type_Union:
return UnionFromFlatbuffer(static_cast<const flatbuf::Union*>(type_data), children,
out);
case flatbuf::Type::Type_RunEndEncoded:
if (children.size() != 2) {
return Status::Invalid("RunEndEncoded must have exactly 2 child fields");
}
if (!is_run_end_type(children[0]->type()->id())) {
return Status::Invalid(
"RunEndEncoded run_ends field must be typed as: int16, int32, or int64");
}
*out =
std::make_shared<RunEndEncodedType>(children[0]->type(), children[1]->type());
return Status::OK();
default:
return Status::Invalid("Unrecognized type: " + ToChars(static_cast<int>(type)));
}
}