Skip to content

Commit 21a09b3

Browse files
committed
feat: Reuse intermediate materialization results
1 parent b26cba4 commit 21a09b3

File tree

3 files changed

+38
-6
lines changed

3 files changed

+38
-6
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/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-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)