@@ -203,7 +203,7 @@ mergepair = function(lhs, rhs, on, how, mult, lhs.cols=names(lhs), rhs.cols=name
203203 copy_x = TRUE
204204 # # ensure no duplicated column names in merge results
205205 if (any(dup.i <- names(out.i ) %chin % names(out.x )))
206- stopf(" merge result has duplicated column names, use 'cols' argument or rename columns in 'l' tables, duplicated column(s): %s " , brackify(names(out.i )[dup.i ]))
206+ stopf(" merge result has duplicated column names [%s] , use 'cols' argument or rename columns in 'l' tables" , brackify(names(out.i )[dup.i ]))
207207 }
208208
209209 # # stack i and x
@@ -216,30 +216,33 @@ mergepair = function(lhs, rhs, on, how, mult, lhs.cols=names(lhs), rhs.cols=name
216216 # # we made left join side above, proceed to right join side, so swap tbls
217217 join_from = rhs ; from_cols = rhs.cols ; join_to = lhs ; to_cols = lhs.cols
218218
219- cp.r = FALSE
219+ copy_r = FALSE
220220 if (! is.null(mult ) && (mult == " first" || mult == " last" )) {
221221 join_from = fdistinct(join_from , on = on , mult = mult , cols = from_cols , copy = FALSE )
222- cp.r = nrow(join_from ) != nrow(rhs ) # # nrow(rhs) bc join_from=rhs
222+ copy_r = nrow(join_from ) != nrow(rhs ) # # nrow(rhs) bc join_from=rhs
223223 } # # mult=="error" check was made on one side already, below we do on the second side, test 101.43
224224
225- # # binary merge anti join
226- bns = dtmerge(x = join_to , i = join_from , on = on , how = " anti" , mult = if (! is.null(mult ) && mult != " all" ) mult , verbose = verbose , join.many = join.many )
225+ # # binary merge anti join; only need to keep 'irows'
226+ mult = if (! is.null(mult ) && mult != " all" ) mult
227+ supplement_rows = dtmerge(x = join_to , i = join_from , on = on , how = " anti" , mult = mult , verbose = verbose , join.many = join.many )$ irows
227228
228229 # # make anti join side
229- out.r = if (is.null(bns $ irows ))
230- .shallow(join_from , cols = someCols(join_from , from_cols , keep = on ), retain.key = TRUE ) # # retain.key is used only in the edge case when !nrow(out.i)
231- else
232- .Call(CsubsetDT , join_from , bns $ irows , someCols(join_from , from_cols , keep = on ))
233- cp.r = cp.r || ! is.null(bns $ irows )
230+ cols_r = someCols(join_from , from_cols , keep = on )
231+ if (is.null(supplement_rows )) {
232+ out.r = .shallow(join_from , cols = cols_r , retain.key = TRUE ) # # retain.key is used only in the edge case when !nrow(out.i)
233+ } else {
234+ out.r = .Call(CsubsetDT , join_from , supplement_rows , cols_r )
235+ copy_r = TRUE
236+ }
234237
235238 # # short circuit to avoid rbindlist to empty sets and retains keys
236239 if (! nrow(out.r )) { # # possibly also !nrow(out.i)
237240 if (! copy_i && copy ) out.i = copy(out.i )
238241 # if (!copy_x && copy) out.x = copy(out.x) ## as of now copy_x always TRUE, search for #4409 here
239242 out = .Call(Ccbindlist , list (out.i , out.x ), FALSE )
240243 } else if (! nrow(out.i )) { # # but not !nrow(out.r)
241- if (! cp.r && copy ) out.r = copy(out.r )
242- if (length(add <- setdiff(names(out.i ), names(out.r )))) { # # add missing columns of proper types NA
244+ if (! copy_r && copy ) out.r = copy(out.r )
245+ if (length(add <- setdiff(names(out.i ), names(out.r )))) { # # add missing columns of proper types NA
243246 neworder = copy(names(out.i )) # set(out.r, NULL, add, lapply(unclass(out.i)[add], `[`, 1L)) ## 291.04 overalloc exceed fail during set()
244247 out.i = lapply(unclass(out.i )[add ], `[` , seq_len(nrow(out.r ))) # # could eventually remove this when cbindlist recycle 0 rows up, note that we need out.r not to be copied
245248 out.r = .Call(Ccbindlist , list (out.r , out.i ), FALSE )
0 commit comments