@@ -299,12 +299,21 @@ static void copy_vec_into(SEXP x, SEXP dst, R_xlen_t offset, R_xlen_t len) {
299299 }
300300}
301301
302- SEXP nanoarrow_materialize_finalize_result (SEXP converter_xptr , SEXP result ) {
303- if (Rf_inherits (result , "nanoarrow_vctr" )) {
302+ int nanoarrow_materialize_finalize_result (SEXP converter_xptr ) {
303+ SEXP converter_shelter = R_ExternalPtrProtected (converter_xptr );
304+ SEXP result = VECTOR_ELT (converter_shelter , 4 );
305+
306+ // Materialize never called (e.g., empty stream)
307+ if (result == R_NilValue ) {
308+ NANOARROW_RETURN_NOT_OK (nanoarrow_converter_reserve (converter_xptr , 0 ));
309+ result = VECTOR_ELT (converter_shelter , 4 );
310+ }
311+
312+ if (nanoarrow_ptype_is_nanoarrow_vctr (result )) {
304313 // Get the schema for this converter. Technically this will overwrite
305314 // a schema that was provided explicitly; however, we currently do not
306315 // handle that case.
307- SEXP converter_shelter = R_ExternalPtrProtected ( converter_xptr );
316+
308317 SEXP schema_xptr = VECTOR_ELT (converter_shelter , 1 );
309318
310319 // We no longer need to keep track of chunks_tail
@@ -333,11 +342,24 @@ SEXP nanoarrow_materialize_finalize_result(SEXP converter_xptr, SEXP result) {
333342 Rf_lang4 (new_nanoarrow_vctr_sym , chunks_list , schema_xptr , subclass_sexp ));
334343 SEXP final_result = PROTECT (Rf_eval (new_nanoarrow_vctr_call , nanoarrow_ns_pkg ));
335344
345+ SET_VECTOR_ELT (converter_shelter , 4 , final_result );
336346 UNPROTECT (6 );
337- return final_result ;
338- } else {
339- return result ;
347+ } else if (nanoarrow_ptype_is_data_frame (result )) {
348+ // For each child, finalize the result and then reassign it
349+ SEXP child_converter_xptrs = VECTOR_ELT (converter_shelter , 3 );
350+ for (R_xlen_t i = 0 ; i < Rf_xlength (child_converter_xptrs ); i ++ ) {
351+ SEXP child_converter_xptr = VECTOR_ELT (child_converter_xptrs , i );
352+ NANOARROW_RETURN_NOT_OK (
353+ nanoarrow_materialize_finalize_result (child_converter_xptr ));
354+
355+ SEXP child_result =
356+ PROTECT (nanoarrow_converter_release_result (child_converter_xptr ));
357+ SET_VECTOR_ELT (result , i , child_result );
358+ UNPROTECT (1 );
359+ }
340360 }
361+
362+ return NANOARROW_OK ;
341363}
342364
343365static int nanoarrow_materialize_nanoarrow_vctr (struct RConverter * converter ,
0 commit comments