Repository navigation
[ntuple] Throw informative error when collection proxy dictionary is missing (#21274) - #23766
ishaaaan17 wants to merge 1 commit into
Conversation
jblomer
left a comment
There was a problem hiding this comment.
In principle looks good to me.
16d0d8a to
ac5db1b
Compare
| // Eagerly check here to avoid low-level assertion failures or segfaults during proxy inspection (issue #21274). | ||
| if (!classp->GetCollectionProxy()) | ||
| throw RException(R__FAIL(std::string(classp->GetName()) + " has no associated collection proxy")); | ||
| if (!classp->HasDictionary()) |
There was a problem hiding this comment.
This condition in itself might be too strict. In particular for the case of std::pair, we only need to have its 2 argument to have a dictionary (or be a pair).
Related, if emulated collection proxy are supported here, the underlying line type would not have a dictionary.
There was a problem hiding this comment.
Correcting myself, the test is not on the containee but on the container. It has the side effect (intentional or not) of prevent the use of emulated collection proxy.
There was a problem hiding this comment.
thanks for the note @pcanal!
yes, it is intentional that RProxiedCollectionField does not allow emulated collection proxies. RProxiedCollectionField depends on compiled iterator function pointers (proxy->GetFunctionCreateIterators(), etc., in RCollectionIterableOnce::GetIteratorFuncs, line 1322), and these are not available for emulated collection proxies.
for on-disk collections that have no compiled dictionary, RNTuple reads them as untyped emulated vector fields (CreateEmulatedVectorField) and not through RProxiedCollectionField.
There was a problem hiding this comment.
iterator function pointers ... and these are not available for emulated collection proxies.
Note that this appears to be inaccurate:
root [0] auto proxy = TClass::GetClass("vector<TObject*>")->GetCollectionProxy()
(TVirtualCollectionProxy *) 0x703a78600
root [1] proxy->GetProperties() & TVirtualCollectionProxy::kIsEmulated
(int) 8
root [2] proxy->GetFunctionCreateIterators()
(TVirtualCollectionProxy::CreateIterators_t) Function @0x108a37508
There was a problem hiding this comment.
thank you @pcanal for pointing this out and checking it! you are right, emulated collection proxies (TEmulatedCollectionProxy) do implement GetFunctionCreateIterators() and give working iterator function pointers.
this is actually why the earlier HasDictionary() check broke TEST(RNTupleEmulated, CollectionProxy). since emulated proxies do have valid iterators, rejecting types based on the container dictionary was too strict.
in the latest commit (a7666f1), i removed the HasDictionary() check completely. the check is now directly in RCollectionIterableOnce::GetIteratorFuncs, where it replaces the low-level R__ASSERT with a ROOT::RException, and it is thrown only when the iterator function pointers are really missing (if (!ifuncs.fCreateIterators || !ifuncs.fDeleteTwoIterators || !ifuncs.fNext)). emulated proxies with valid iterators keep working as before.
5281515 to
721fe94
Compare
Test Results 24 files 24 suites 3d 11h 14m 40s ⏱️ For more details on these failures, see this check. Results for commit 721fe94. |
721fe94 to
0246690
Compare
|
following up on this @pcanal, you were right. the CI showed that so i changed the fix to check what we really depend on. instead of checking this catches missing compiled iterators and does not affect emulated or custom proxies. the tests in this catches missing compiled iterators and does not affect emulated or custom proxies. @jblomer could you please trigger or approve the CI workflows for the updated commit? thanks! |
0246690 to
adb5e67
Compare
|
hi @jblomer, i checked the CI failures on i have removed that assertion, so now only the exception check in could you please re-trigger the CI workflows when you get time? thank you! |
|
Would still be nice to have a test for this. You can perhaps check the evolution tests and their forking mechanism for a blueprint. |
adb5e67 to
5c71dab
Compare
|
@jblomer added the test, it defines a proxied collection type with no iterator functions and checks that |
5c71dab to
a7666f1
Compare
summary of changes
fixes #21274.
when an RNTuple collection proxy field (for example
std::setorstd::map) was created for a type that has no dictionary, ROOT hit an assertion failure inTGenCollectionProxy.cxx:401(R__ASSERT(e->IsValid())), or failed while inspecting the collection proxy.this change:
classp->HasDictionary()in the constructor ofRProxiedCollectionField, before the collection proxy is generated, and throws aROOT::RExceptionwith the name of the missing type ("<type> has no dictionary entry available").tree/ntuple/test/ntuple_types.cxxunderTEST(RNTuple, TVirtualCollectionProxy). it checks that a collection type without a loaded dictionary (std::map<double, double>) throws aROOT::RExceptionwith this error message.checklist
.clang-formatai disclosure
Assisted-by: antigravity:gemini. i used an ai assistant to follow the collection proxy generation call stack in
RProxiedCollectionFieldandTGenCollectionProxy. i checked the dictionary lookup againstTClass::HasDictionary(), wrote the unit test and the exception check, and checked the formatting with.clang-format.