Skip to content

Commit 27992b1

Browse files
committed
feat: Reuse intermediate materialization results
1 parent b26cba4 commit 27992b1

File tree

5 files changed

+46
-8
lines changed

5 files changed

+46
-8
lines changed

R/relational-duckdb.R

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,13 @@ duckdb_rel_from_df <- function(df, call = caller_env()) {
9999
# FIXME: make generic
100100
stopifnot(is.data.frame(df))
101101

102-
rel <- duckdb$rel_from_altrep_df(df, strict = FALSE, allow_materialized = FALSE)
102+
rel <- duckdb$rel_from_altrep_df(
103+
df,
104+
strict = FALSE,
105+
allow_materialized = FALSE,
106+
wrap = TRUE
107+
)
108+
103109
if (!is.null(rel)) {
104110
# Once we're here, we know it's an ALTREP data frame
105111
# We don't get here if it's already materialized

tests/testthat/_snaps/compute.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
---------------------
88
--- Relation Tree ---
99
---------------------
10-
Scan Table [duckplyr_4hYuvhNS26]
10+
AltrepDataFrame [0xdeadbeef]
11+
Scan Table [duckplyr_4hYuvhNS26]
1112
1213
---------------------
1314
-- Result Columns --

tests/testthat/_snaps/relational-duckdb.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,12 @@
4242
---------------------
4343
--- Relation Tree ---
4444
---------------------
45-
Projection [a as a]
46-
Order [___row_number ASC]
47-
Filter [(a = 1.0)]
48-
Projection [a as a, row_number() OVER () as ___row_number]
49-
r_dataframe_scan(0xdeadbeef)
45+
AltrepDataFrame [0xdeadbeef]
46+
Projection [a as a]
47+
Order [___row_number ASC]
48+
Filter [(a = 1.0)]
49+
Projection [a as a, row_number() OVER () as ___row_number]
50+
r_dataframe_scan(0xdeadbeef)
5051
5152
---------------------
5253
-- Result Columns --

tests/testthat/test-compute.R

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
test_that("compute()", {
22
set.seed(20241230)
33

4+
transform <- function(x) {
5+
x <- gsub("0x[0-9a-f]+", "0xdeadbeef", x)
6+
x
7+
}
8+
49
df <- duckdb_tibble(x = c(1, 2))
510
out <- compute(df)
6-
expect_snapshot({
11+
expect_snapshot(transform = transform, {
712
duckdb_rel_from_df(out)
813
})
914

tests/testthat/test-relational-duckdb.R

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,3 +138,28 @@ test_that("duckdb_rel_from_df() uses materialized results", {
138138

139139
expect_equal(n_calls, 1)
140140
})
141+
142+
test_that("duckdb_rel_from_df() uses materialized intermediate results", {
143+
skip_if(identical(Sys.getenv("R_COVR"), "true"))
144+
145+
withr::local_envvar(DUCKPLYR_OUTPUT_ORDER = FALSE)
146+
147+
df1 <- duckdb_tibble(a = 1)
148+
df2 <- df1 |> arrange(a)
149+
df3 <- df2 |> mutate(b = 2)
150+
151+
rel2 <- duckdb:::rel_from_altrep_df(df2, wrap = TRUE)
152+
expect_length(strsplit(duckdb:::rel_tostring(rel2, "tree"), "\n")[[1]], 4)
153+
154+
rel3 <- duckdb:::rel_from_altrep_df(df3, wrap = TRUE)
155+
expect_length(strsplit(duckdb:::rel_tostring(rel3, "tree"), "\n")[[1]], 6)
156+
157+
# Side effect: trigger intermediate materialization
158+
nrow(df2)
159+
160+
# The depth of the rel2 tree is shorter thanks to `wrap = TRUE`
161+
expect_length(strsplit(duckdb:::rel_tostring(rel2, "tree"), "\n")[[1]], 2)
162+
163+
# The depth of the rel3 tree is shorter now too
164+
expect_length(strsplit(duckdb:::rel_tostring(rel3, "tree"), "\n")[[1]], 4)
165+
})

0 commit comments

Comments
 (0)