Skip to content

Commit 818170f

Browse files
tarun-taitap
authored andcommitted
Fix non-equi join error with equi + 2 inequality conditions (#7642)
* Fix non-equi join error with equi + 2 inequality conditions (#7641) When rightcols contains duplicates (same x column in multiple non-equi conditions), chmatchdup remaps them into the expanded result namespace. This overwrote rightcols, causing downstream code (e.g. .shallow(x, rightcols) in .join_result_key) to reference columns beyond ncol(x). Introduce ansrightcols for the remapped indices and keep rightcols as original column indices into x. Only icolsAns needs the remapped values; all other uses (xcols, names_x[rightcols], .join_result_key) need the original x-relative indices. Closes #7641 * Add contributor credit in DESCRIPTION and NEWS Per reviewer request: thank reporter in NEWS.md and add Tarun Thammisetty as contributor to DESCRIPTION.
1 parent edcab12 commit 818170f

4 files changed

Lines changed: 17 additions & 4 deletions

File tree

DESCRIPTION

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,5 +106,6 @@ Authors@R: c(
106106
person("Vinit", "Thakur", role="ctb"),
107107
person("Mukul", "Kumar", role="ctb"),
108108
person("Ildikó", "Czeller", role="ctb"),
109-
person("Manmita", "Das", role="ctb")
109+
person("Manmita", "Das", role="ctb"),
110+
person("Tarun", "Thammisetty", role="ctb")
110111
)

NEWS.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44

55
## data.table [v1.18.3](https://github.com/Rdatatable/data.table/milestone/45?closed=1)
66

7+
### BUG FIXES
8+
9+
1. Non-equi joins combining an equality condition with two inequality conditions on the same column (e.g., `on = .(id == id, val >= lo, val <= hi)`) no longer error, [#7641](https://github.com/Rdatatable/data.table/issues/7641). The internal `chmatchdup` remapping of duplicate `rightcols` was overwriting the original column indices, causing downstream code to reference non-existent columns. Thanks @tarun-t for the report and fix, and @aitap for the diagnosis.
10+
711
## data.table [v1.18.2.1](https://github.com/Rdatatable/data.table/milestone/44?closed=1) 22 Jan 2026
812

913
### BUG FIXES

R/data.table.R

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -701,12 +701,15 @@ replace_dot_alias = function(e) {
701701
if (length(tt)) jisvars[tt] = paste0("i.",jisvars[tt])
702702
if (length(duprightcols <- rightcols[duplicated(rightcols)])) {
703703
nx = c(names_x, names_x[duprightcols])
704-
rightcols = chmatchdup(names_x[rightcols], nx)
704+
ansrightcols = chmatchdup(names_x[rightcols], nx) # indices into result namespace nx, #7641
705705
nx = make.unique(nx)
706-
} else nx = names_x
706+
} else {
707+
nx = names_x
708+
ansrightcols = rightcols
709+
}
707710
ansvars = make.unique(c(nx, jisvars))
708711
icols = c(leftcols, seq_along(i)[-leftcols])
709-
icolsAns = c(rightcols, seq.int(length(nx)+1L, length.out=ncol(i)-length(unique(leftcols))))
712+
icolsAns = c(ansrightcols, seq.int(length(nx)+1L, length.out=ncol(i)-length(unique(leftcols))))
710713
xcols = xcolsAns = seq_along(x)[-rightcols]
711714
}
712715
ansvals = chmatch(ansvars, nx)

inst/tests/tests.Rraw

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7153,6 +7153,11 @@ DT1 <- data.table(a=1L, key='a')
71537153
DT2 <- data.table(a=2.0, key='a')
71547154
test(1483.83, DT1[DT2, roll='nearest'], data.table(a=2L, key='a'))
71557155

7156+
# non-equi join with equi + 2 inequality conditions should not error, #7641
7157+
dt_x = data.table(id = c("A","A","B","B"), val = c(1,5,2,4), key = c("id","val"))
7158+
dt_i = data.table(id = c("A","B"), lo = c(2,1), hi = c(6,3))
7159+
test(1483.91, nrow(dt_x[dt_i, on = .(id == id, val >= lo, val <= hi)]), 2L)
7160+
71567161
# NULL items should be removed when making data.table from list, #842
71577162
# Original fix for #842 added a branch in as.data.table.list() using point()
71587163
# Then PR#3471 moved logic from data.table() into as.data.table.list() and now removes NULL items up front, so longer need for the branch

0 commit comments

Comments
 (0)