diff --git a/NEWS.md b/NEWS.md index 9de21ce6f..daa815151 100644 --- a/NEWS.md +++ b/NEWS.md @@ -58,6 +58,8 @@ 12. `print.data.table()` now truncates long character columns and list-column summaries by default to avoid horizontal console overflow, [#7718](https://github.com/Rdatatable/data.table/issues/7718). When `datatable.prettyprint.char` is `NULL` (the default), the truncation limit is now dynamically calculated based on the available console width. Use `options(datatable.prettyprint.char=Inf)` for the old default behavior (never truncate). Thanks @tdhock for the report and @venom1204 for the fix. +13. `rbindlist()` (and therefore the `rbind()` method for `data.table`s) no longer raises an error upon encountering more than approximately 50000 columns in a list entry, [#7793](https://github.com/Rdatatable/data.table/issues/7793). The bug was introduced in `data.table` version 1.18.2.1. Thanks to @rickhelmus for the report and @aitap for the fix. + ### Notes 1. {data.table} now depends on R 3.5.0 (2018). diff --git a/inst/tests/tests.Rraw b/inst/tests/tests.Rraw index 90e33145e..8c1a0deb0 100644 --- a/inst/tests/tests.Rraw +++ b/inst/tests/tests.Rraw @@ -21669,3 +21669,9 @@ test(2375.3, print(data.table(x=c("short", "abcdefghijklmnopqrstuvwxyz"))), outp test(2375.4, print(data.table(x="abcdefghijklmnopqrstuvwxyz")), output="abcdefghijklmnopqrstuvwxyz", options=list(width=200, datatable.prettyprint.char=NULL)) test(2375.5, print(data.table(id=1L, score=99.1, txt="abcdefghijklmnopqrstuvwxyz")), output="abcdefghijklmn...", options=list(width=20, datatable.prettyprint.char=NULL)) test(2375.6, print(data.table(x=rep("ABCDEFGHIJKLMNOPQRSTUVWXYZ", 1e6)), topn=1), output="1000000: ABCDEFGHIJKLM...", options=list(width=25, datatable.prettyprint.char=NULL)) + +# rbindlist() used to put O(ncol(...)) > R_PPStackSize items on the protect stack, #7793 +# Assuming 50000 as the default protection stack size, although R --max-ppsize=... can increase it to 500000. +x = as.data.table(as.list(1:50001)) +test(2376, rbindlist(list(x)), x) +rm(x) diff --git a/src/rbindlist.c b/src/rbindlist.c index e8159c1ef..d7ac8d816 100644 --- a/src/rbindlist.c +++ b/src/rbindlist.c @@ -250,7 +250,7 @@ SEXP rbindlist(SEXP l, SEXP usenamesArg, SEXP fillArg, SEXP idcolArg, SEXP ignor setAttrib(ans, R_NamesSymbol, ansNames); if (idcol) { SET_STRING_ELT(ansNames, 0, STRING_ELT(idcolArg, 0)); - SEXP idval, listNames=getAttrib(l, R_NamesSymbol); + SEXP idval, listNames=PROTECT(getAttrib(l, R_NamesSymbol)); if (length(listNames)) { SET_VECTOR_ELT(ans, 0, idval=allocVector(STRSXP, nrow)); for (int i=0,ansloc=0; i