diff --git a/inst/tests/tests.Rraw b/inst/tests/tests.Rraw index 099726a96..80f50f66b 100644 --- a/inst/tests/tests.Rraw +++ b/inst/tests/tests.Rraw @@ -18856,3 +18856,7 @@ x = data.table(a = 1L, b = as.Date("2020-01-01")) y = data.table(a = 2L, b = NA) test(2239.23, merge(x, y, by="a", all=TRUE), data.table(a=1:2, b.x=as.Date(c("2020-01-01", NA)), b.y=NA, key="a")) test(2239.24, merge(y, x, by="a", all=TRUE), data.table(a=1:2, b.x=NA, key="a", b.y=as.Date(c("2020-01-01", NA)))) +x = data.table(a = 1L, b=I(3L)) +y = data.table(a = 2L, b=NA) +test(2239.25, rbind(x,y), data.table(a = c(1L, 2L), b=I(c(3L, NA)))) +test(2239.26, rbind(y,x), data.table(a = c(2L, 1L), b=c(NA, 3L))) diff --git a/src/data.table.h b/src/data.table.h index b966e86c0..2068d4570 100644 --- a/src/data.table.h +++ b/src/data.table.h @@ -90,6 +90,7 @@ extern SEXP char_datatable; extern SEXP char_dataframe; extern SEXP char_NULL; extern SEXP char_maxString; +extern SEXP char_AsIs; extern SEXP sym_sorted; extern SEXP sym_index; extern SEXP sym_BY; diff --git a/src/init.c b/src/init.c index 284c30b4f..ae2c68243 100644 --- a/src/init.c +++ b/src/init.c @@ -23,6 +23,7 @@ SEXP char_datatable; SEXP char_dataframe; SEXP char_NULL; SEXP char_maxString; +SEXP char_AsIs; SEXP sym_sorted; SEXP sym_index; SEXP sym_BY; @@ -348,6 +349,7 @@ void attribute_visible R_init_data_table(DllInfo *info) char_dataframe = PRINTNAME(install("data.frame")); char_NULL = PRINTNAME(install("NULL")); char_maxString = PRINTNAME(install("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF")); + char_AsIs = PRINTNAME(install("AsIs")); if (TYPEOF(char_integer64) != CHARSXP) { // checking one is enough in case of any R-devel changes diff --git a/src/rbindlist.c b/src/rbindlist.c index a5d994926..20218c3e2 100644 --- a/src/rbindlist.c +++ b/src/rbindlist.c @@ -274,10 +274,7 @@ SEXP rbindlist(SEXP l, SEXP usenamesArg, SEXP fillArg, SEXP idcolArg) bool factor=false, orderedFactor=false; // ordered factor is class c("ordered","factor"). isFactor() is true when isOrdered() is true. int longestLen=-1, longestW=-1, longestI=-1; // just for ordered factor; longestLen must be initialized as -1 so that rbind zero-length ordered factor could work #4795 SEXP longestLevels=R_NilValue; // just for ordered factor - bool int64=false; - bool date=false; - bool posixct=false; - bool itime=false; + bool int64=false, date=false, posixct=false, itime=false, asis=false; const char *foundName=NULL; bool anyNotStringOrFactor=false; SEXP firstCol=R_NilValue; @@ -317,10 +314,12 @@ SEXP rbindlist(SEXP l, SEXP usenamesArg, SEXP fillArg, SEXP idcolArg) } else if (INHERITS(thisCol, char_ITime)) { if (firsti>=0 && !length(getAttrib(firstCol, R_ClassSymbol))) { firsti=i; firstw=w; firstCol=thisCol; } itime=true; + } else if (!asis && INHERITS(thisCol, char_AsIs)) { + asis=true; } if (firsti==-1) { firsti=i; firstw=w; firstCol=thisCol; } else { - if (!factor && !int64 && ((!date && !posixct) || (date && posixct)) && !itime) { // prohibit binding of date and posixct + if (!factor && !int64 && ((!date && !posixct) || (date && posixct)) && !itime &!asis) { // prohibit binding of date and posixct if (!R_compute_identical(PROTECT(getAttrib(thisCol, R_ClassSymbol)), PROTECT(getAttrib(firstCol, R_ClassSymbol)), 0)) {