diff --git a/R/data.table.R b/R/data.table.R index 3893fe2fc..65bd26f31 100644 --- a/R/data.table.R +++ b/R/data.table.R @@ -2848,6 +2848,14 @@ setcolorder = function(x, neworder=key(x), before=NULL, after=NULL, skip_absent= set = function(x,i=NULL,j,value) # low overhead, loopable { + # If removing columns from a table that's not selfrefok, need to call setalloccol first, #7488 + if ((is.null(value) || (is.list(value) && any(vapply_1b(value, is.null)))) && selfrefok(x, verbose=FALSE) < 1L) { + name = substitute(x) + setalloccol(x, verbose=FALSE) + if (is.name(name)) { + assign(as.character(name), x, parent.frame(), inherits=TRUE) + } + } .Call(Cassign,x,i,j,NULL,value) invisible(x) } diff --git a/inst/tests/tests.Rraw b/inst/tests/tests.Rraw index 91e6bc580..0eae9856c 100644 --- a/inst/tests/tests.Rraw +++ b/inst/tests/tests.Rraw @@ -21898,7 +21898,14 @@ rm(DT, strings) # do remove columns in freshly unserialized data.tables, #7488 DT = unserialize(serialize(as.data.table(mtcars), NULL)) -test(2351, DT[,carb:=NULL], as.data.table(mtcars)[,carb:=NULL]) +test(2351.1, DT[,carb:=NULL], as.data.table(mtcars)[,carb:=NULL]) +DT = unserialize(serialize(as.data.table(mtcars), NULL)) +test(2351.2, set(DT, j="carb", value=NULL), as.data.table(mtcars)[,carb:=NULL]) +DT = unserialize(serialize(as.data.table(mtcars), NULL)) +null_in_value <- NULL +test(2351.3, "cyl" %notin% names(DT[, cyl := null_in_value])) +DT = unserialize(serialize(as.data.table(mtcars), NULL)) +test(2351.4, ncol(DT[, c("cyl", "mpg") := .(null_in_value, null_in_value)]), ncol(mtcars) - 2L) rm(DT) # rbindlist did not protect the temporary UTF-8 strings, #7452