diff --git a/src/assign.c b/src/assign.c index ef3542f770..42a4022b27 100644 --- a/src/assign.c +++ b/src/assign.c @@ -475,7 +475,7 @@ SEXP assign(SEXP dt, SEXP rows, SEXP cols, SEXP newcolnames, SEXP values) Rprintf("RHS for item %d has been duplicated because NAMED==%d MAYBE_SHARED==%d, but then is being plonked. length(values)==%d; length(cols)==%d)\n", i+1, NAMED(thisvalue), MAYBE_SHARED(thisvalue), length(values), length(cols)); } - thisvalue = duplicate(thisvalue); // PROTECT not needed as assigned as element to protected list below. + thisvalue = copyAsPlain(thisvalue); // PROTECT not needed as assigned as element to protected list below. } else { if (verbose) Rprintf("Direct plonk of unnamed RHS, no copy. NAMED==%d, MAYBE_SHARED==%d\n", NAMED(thisvalue), MAYBE_SHARED(thisvalue)); // e.g. DT[,a:=as.character(a)] as tested by 754.5 } @@ -564,7 +564,7 @@ SEXP assign(SEXP dt, SEXP rows, SEXP cols, SEXP newcolnames, SEXP values) if (iRHS[0] != NA_INTEGER) warning("Coerced '%s' RHS to 'integer' to match the factor column's underlying type. Character columns are now recommended (can be in keys), or coerce RHS to integer or character first.", type2char(TYPEOF(thisvalue))); } else { // thisvalue is integer // make sure to copy thisvalue. May be modified below. See #2984 - RHS = PROTECT(duplicate(thisvalue)); thisprotecti++; + RHS = PROTECT(copyAsPlain(thisvalue)); thisprotecti++; iRHS = INTEGER(RHS); } for (int j=0; j maxSize) maxSize=SIZEOF(v); - if (ALTREP(v)) SET_VECTOR_ELT(x,i,duplicate(v)); // expand compact vector in place ready for reordering by reference + if (ALTREP(v)) SET_VECTOR_ELT(x, i, copyAsPlain(v)); } copySharedColumns(x); // otherwise two columns which point to the same vector would be reordered and then re-reordered, issues linked in PR#3768 } else { @@ -33,7 +33,7 @@ SEXP reorder(SEXP x, SEXP order) if (!isInteger(order)) error("order must be an integer vector"); if (length(order) != nrow) error("nrow(x)[%d]!=length(order)[%d]",nrow,length(order)); int nprotect = 0; - if (ALTREP(order)) { order=PROTECT(duplicate(order)); nprotect++; } // TODO: how to fetch range of ALTREP compact vector + if (ALTREP(order)) { order=PROTECT(copyAsPlain(order)); nprotect++; } // TODO: if it's an ALTREP sequence some optimizations are possible rather than expand const int *restrict idx = INTEGER(order); int i=0; diff --git a/src/subset.c b/src/subset.c index 7891a36dd5..f9426bb402 100644 --- a/src/subset.c +++ b/src/subset.c @@ -281,7 +281,7 @@ SEXP subsetDT(SEXP x, SEXP rows, SEXP cols) { for (int i=0; i make.levels -> rbindlist -> [ -> [.data.table + // Perhaps related to row names and the copyMostAttrib() below is not quite sufficient + + size_t n = XLENGTH(x); + SEXP ans = PROTECT(allocVector(TYPEOF(x), XLENGTH(x))); + switch (TYPEOF(ans)) { + case RAWSXP: + memcpy(RAW(ans), RAW(x), n*sizeof(Rbyte)); // # nocov; add coverage when ALTREP is turned on for all types + break; // # nocov + case LGLSXP: + memcpy(LOGICAL(ans), LOGICAL(x), n*sizeof(Rboolean)); // # nocov + break; // # nocov + case INTSXP: + memcpy(INTEGER(ans), INTEGER(x), n*sizeof(int)); // covered by 10:1 after test 178 + break; + case REALSXP: + memcpy(REAL(ans), REAL(x), n*sizeof(double)); // covered by as.Date("2013-01-01")+seq(1,1000,by=10) after test 1075 + break; + case CPLXSXP: + memcpy(COMPLEX(ans), COMPLEX(x), n*sizeof(Rcomplex)); // # nocov + break; // # nocov + case STRSXP: { + const SEXP *xp=STRING_PTR(x); // covered by as.character(as.hexmode(1:500)) after test 642 + for (R_xlen_t i=0; i1?"s":""); // GetVerbose() (slightly expensive call of all options) called here only when needed diff --git a/src/wrappers.c b/src/wrappers.c index 2dc98264ac..928be0c05a 100644 --- a/src/wrappers.c +++ b/src/wrappers.c @@ -93,7 +93,7 @@ SEXP expandAltRep(SEXP x) for (int i=0; i