Skip to content

Commit 97bbf8c

Browse files
committed
Fail loudly on graphs beyond the 32-bit node range
DuckDBSelfHits() coerced nnode (and supplied node ids) with as.integer(), which silently produced NA above 2^31 and corrupted graph reconstruction at read time. It now errors with an explicit message when nnode or a node id exceeds the 32-bit integer range; graphs with more than ~2.1e9 nodes are not yet supported (the node-id slots are 32-bit). Behavior within the 32-bit range is unchanged. This closes the read-side half of the > 2^31 hardening: the write path can now emit a > 2^31-edge graph index (BiocDuckDB writeParquet index_max), so a huge node count must fail at construction rather than silently become NA. Bump version to 0.99.4; update NEWS.
1 parent ad25e5e commit 97bbf8c

4 files changed

Lines changed: 32 additions & 1 deletion

File tree

DESCRIPTION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
Package: DuckDBDataFrame
2-
Version: 0.99.3
2+
Version: 0.99.4
33
Date: 2026-07-22
44
Title: DuckDB-Backed DataFrame and Table Structures
55
Description:

NEWS.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
# DuckDBDataFrame 0.99.4
2+
3+
## Bug fixes
4+
5+
- `DuckDBSelfHits()` now fails loudly when `nnode` (or a supplied node id)
6+
exceeds the 32-bit integer range, instead of letting `as.integer()` silently
7+
coerce it to `NA` (which corrupted graph reconstruction). Graphs with more
8+
than ~2.1e9 nodes are not yet supported; the error says so explicitly.
9+
110
# DuckDBDataFrame 0.99.3
211

312
## Bug fixes

R/DuckDBSelfHits-class.R

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,14 @@ function(conn, from, to, nnode, mcols = NULL, keycol = NULL, dimtbl = NULL, node
448448
stop("'nnode' must be a single non-negative integer")
449449
}
450450

451+
# Node ids are held in 32-bit integer slots. Fail loudly on a > 2^31-node
452+
# graph rather than letting as.integer() silently coerce nnode to NA (which
453+
# would corrupt reconstruction at read time).
454+
if (nnode > .Machine$integer.max) {
455+
stop("'nnode' (", format(nnode, scientific = FALSE), ") exceeds the ",
456+
"32-bit integer range; graphs with more than ",
457+
.Machine$integer.max, " nodes are not yet supported.")
458+
}
451459
if (!is.integer(nnode)) {
452460
nnode <- as.integer(nnode)
453461
}
@@ -457,6 +465,10 @@ function(conn, from, to, nnode, mcols = NULL, keycol = NULL, dimtbl = NULL, node
457465
} else if (!is.numeric(nodes)) {
458466
stop("'nodes' must be a numeric vector")
459467
} else {
468+
if (any(nodes > .Machine$integer.max, na.rm = TRUE)) {
469+
stop("'nodes' contains ids beyond the 32-bit integer range; node ",
470+
"ids above ", .Machine$integer.max, " are not yet supported.")
471+
}
460472
if (!is.integer(nodes)) {
461473
nodes <- as.integer(nodes)
462474
}

tests/testthat/test-DuckDBSelfHits.R

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,3 +351,13 @@ test_that("isolated node subset produces empty result for a DuckDBSelfHits", {
351351
expect_identical(nnode(sub), 1L)
352352
expect_identical(nrow(as.data.frame(sub)), 0L)
353353
})
354+
355+
test_that("nnode / node ids beyond the 32-bit range fail loudly (not silent NA)", {
356+
expect_error(
357+
DuckDBSelfHits(selfhits_parquet, from = "from", to = "to", nnode = 3e9),
358+
"32-bit")
359+
expect_error(
360+
DuckDBSelfHits(selfhits_parquet, from = "from", to = "to", nnode = 5L,
361+
nodes = c(1, 3e9)),
362+
"32-bit")
363+
})

0 commit comments

Comments
 (0)