From 38e71de3c92e60fa81e0248fe8ff995db5af8eff Mon Sep 17 00:00:00 2001 From: Jakob Blomer Date: Thu, 5 Nov 2026 22:53:13 +0100 Subject: [PATCH] [ntuple] fix recreation of streamer field with type alias --- tree/ntuple/src/RNTupleDescriptor.cxx | 3 ++- tree/ntuple/test/StreamerField.hxx | 10 ++++++++++ tree/ntuple/test/StreamerFieldLinkDef.h | 3 +++ tree/ntuple/test/rfield_streamer.cxx | 18 ++++++++++++++++++ 4 files changed, 33 insertions(+), 1 deletion(-) diff --git a/tree/ntuple/src/RNTupleDescriptor.cxx b/tree/ntuple/src/RNTupleDescriptor.cxx index 791ec2deb78cb..7641f1fda0760 100644 --- a/tree/ntuple/src/RNTupleDescriptor.cxx +++ b/tree/ntuple/src/RNTupleDescriptor.cxx @@ -82,7 +82,8 @@ std::unique_ptr ROOT::RFieldDescriptor::CreateField(const RNTupleDescriptor &ntplDesc, const ROOT::RCreateFieldOptions &options) const { if (GetStructure() == ROOT::ENTupleStructure::kStreamer) { - auto streamerField = std::make_unique(GetFieldName(), GetTypeName()); + const auto &typeName = GetTypeAlias().empty() ? GetTypeName() : GetTypeAlias(); + auto streamerField = std::make_unique(GetFieldName(), typeName); if ((streamerField->GetTraits() & RFieldBase::kTraitEmulatedField) && !options.GetEmulateUnknownTypes()) { throw RException( R__FAIL("streamer field " + GetFieldName() + " has an emulated class but emulation is turned off")); diff --git a/tree/ntuple/test/StreamerField.hxx b/tree/ntuple/test/StreamerField.hxx index cf5d29d4d26bc..90e903155609a 100644 --- a/tree/ntuple/test/StreamerField.hxx +++ b/tree/ntuple/test/StreamerField.hxx @@ -101,4 +101,14 @@ struct TemperatureKelvin { float fValue; }; +template +struct MEtoEDMStreamer { + T fMember; +}; + +template +struct MEtoEDMClass { + T fMember; +}; + #endif // ROOT_RNTuple_Test_StreamerField diff --git a/tree/ntuple/test/StreamerFieldLinkDef.h b/tree/ntuple/test/StreamerFieldLinkDef.h index 59010c53264e4..1686bbee7938c 100644 --- a/tree/ntuple/test/StreamerFieldLinkDef.h +++ b/tree/ntuple/test/StreamerFieldLinkDef.h @@ -27,4 +27,7 @@ #pragma link C++ options = rntupleStreamerMode(true) class TemperatureCelsius + ; #pragma link C++ options = rntupleStreamerMode(true) class TemperatureKelvin + ; +#pragma link C++ options = rntupleStreamerMode(true) class MEtoEDMStreamer+; +#pragma link C++ class MEtoEDMClass+; + #endif diff --git a/tree/ntuple/test/rfield_streamer.cxx b/tree/ntuple/test/rfield_streamer.cxx index 2f6e82ae85e33..1512632da9e44 100644 --- a/tree/ntuple/test/rfield_streamer.cxx +++ b/tree/ntuple/test/rfield_streamer.cxx @@ -407,3 +407,21 @@ TEST(RField, StreamerClassMismatch) false /* matchFullMessage */); reader->LoadEntry(0); } + +TEST(RField, StreamerLong64TemplateArg) +{ + FileRaii fileGuard("test_ntuple_rfield_streamer_long64_template_arg.root"); + { + auto model = RNTupleModel::Create(); + model->AddField(RFieldBase::Create("s", "MEtoEDMStreamer").Unwrap()); + model->AddField(RFieldBase::Create("c", "MEtoEDMClass").Unwrap()); + auto writer = RNTupleWriter::Recreate(std::move(model), "ntpl", fileGuard.GetPath()); + writer->Fill(); + } + + auto reader = RNTupleReader::Open("ntpl", fileGuard.GetPath()); + const auto &s = dynamic_cast(reader->GetModel().GetConstField("s")); + EXPECT_STREQ("MEtoEDMStreamer", s.GetClass()->GetName()); + const auto &c = dynamic_cast(reader->GetModel().GetConstField("c")); + EXPECT_STREQ("MEtoEDMClass", c.GetClass()->GetName()); +}