diff --git a/R/data.table.R b/R/data.table.R index 3fe2ba8e1f..b8c1132f6a 100644 --- a/R/data.table.R +++ b/R/data.table.R @@ -223,7 +223,10 @@ replace_dot_alias = function(e) { missingnomatch = missing(nomatch) nomatch0 = identical(nomatch,0) || identical(nomatch,0L) || identical(nomatch, FALSE) # for warning with row-numbers in i; #4353 if (nomatch0) nomatch=NULL # retain nomatch=0|FALSE backwards compatibility, #857 #5214 - if (!(is.null(nomatch) || (length(nomatch)==1L && is.na(nomatch)))) stopf("nomatch= must be either NA or NULL (or 0 for backwards compatibility which is the same as NULL but please use NULL)") + if (!is.null(nomatch)) { + if (!(length(nomatch)==1L && is.na(nomatch))) stopf("nomatch= must be either NA or NULL (or 0 for backwards compatibility which is the same as NULL but please use NULL)") + nomatch=NA # convert NA_character_ to NA-logical, PR#5216 + } if (!is.logical(which) || length(which)>1L) stopf("which= must be a logical vector length 1. Either FALSE, TRUE or NA.") if ((isTRUE(which)||is.na(which)) && !missing(j)) stopf("which==%s (meaning return row numbers) but j is also supplied. Either you need row numbers or the result of j, but only one type of result can be returned.", which) if (is.null(nomatch) && is.na(which)) stopf("which=NA with nomatch=0|NULL would always return an empty vector. Please change or remove either which or nomatch.") diff --git a/inst/tests/tests.Rraw b/inst/tests/tests.Rraw index 18fb5c82a5..ef4ed3a614 100644 --- a/inst/tests/tests.Rraw +++ b/inst/tests/tests.Rraw @@ -18271,7 +18271,8 @@ DT = data.table(A=1:3) class(DT) = "data.table" test(2222, print(DT), output="A.*3") -# retain nomatch=FALSE backwards compatibility, #5214 +# retain nomatch=FALSE backwards compatibility #5214, and nomatch=NA_character_ PR#5216 DT = data.table(A=1:3, key="A") -test(2223, DT[.(4), nomatch=FALSE], data.table(A=integer(), key="A")) +test(2223.1, DT[.(4), nomatch=FALSE], data.table(A=integer(), key="A")) +test(2223.2, DT[.(4), nomatch=NA_character_], data.table(A=4L, key="A")) diff --git a/src/bmerge.c b/src/bmerge.c index 44ac7b569c..1011c84aab 100644 --- a/src/bmerge.c +++ b/src/bmerge.c @@ -85,7 +85,15 @@ SEXP bmerge(SEXP idt, SEXP xdt, SEXP icolsArg, SEXP xcolsArg, SEXP isorted, SEXP error(_("rollends must be a length 2 logical vector")); rollends = LOGICAL(rollendsArg); - nomatch = isNull(nomatchArg) ? 0 : INTEGER(nomatchArg)[0]; + if (isNull(nomatchArg)) { + nomatch=0; + } else { + if (length(nomatchArg)!=1 || (!isLogical(nomatchArg) && !isInteger(nomatchArg))) + error(_("Internal error: nomatchArg must be NULL or length-1 logical/integer")); // # nocov + nomatch = INTEGER(nomatchArg)[0]; + if (nomatch!=NA_INTEGER && nomatch!=0) + error(_("Internal error: nomatchArg must be NULL, NA, NA_integer_ or 0L")); // # nocov + } // mult arg if (!strcmp(CHAR(STRING_ELT(multArg, 0)), "all")) mult = ALL;