From 6fa71093fdaa90003735b1af2bfec2a47a52f74b Mon Sep 17 00:00:00 2001 From: Antonov548 Date: Mon, 6 Jan 2025 16:32:31 +0100 Subject: [PATCH 01/69] feat: add `AltrepDataFrameRelation` class --- src/CMakeLists.txt | 1 + src/Makevars | 2 +- src/altrepdataframe_relation.cpp | 22 ++++++++++++++++++++++ src/include/altrepdataframe_relation.hpp | 17 +++++++++++++++++ 4 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 src/altrepdataframe_relation.cpp create mode 100644 src/include/altrepdataframe_relation.hpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c1f9fc98a..ca417c971 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -10,6 +10,7 @@ add_library( register.cpp relational.cpp reltoaltrep.cpp + altrepdataframe_relation.cpp scan.cpp statement.cpp transform.cpp diff --git a/src/Makevars b/src/Makevars index 0eff645a7..939f119ea 100644 --- a/src/Makevars +++ b/src/Makevars @@ -16,4 +16,4 @@ include Makevars.duckdb CXX_STD = CXX17 PKG_CPPFLAGS = -Iinclude -I../inst/include -DDUCKDB_DISABLE_PRINT -DDUCKDB_R_BUILD -DBROTLI_ENCODER_CLEANUP_ON_OOM -Iduckdb/src/include -Iduckdb/third_party/concurrentqueue -Iduckdb/third_party/fast_float -Iduckdb/third_party/fastpforlib -Iduckdb/third_party/fmt/include -Iduckdb/third_party/fsst -Iduckdb/third_party/httplib -Iduckdb/third_party/hyperloglog -Iduckdb/third_party/jaro_winkler -Iduckdb/third_party/jaro_winkler/details -Iduckdb/third_party/libpg_query -Iduckdb/third_party/libpg_query/include -Iduckdb/third_party/lz4 -Iduckdb/third_party/brotli/include -Iduckdb/third_party/brotli/common -Iduckdb/third_party/brotli/dec -Iduckdb/third_party/brotli/enc -Iduckdb/third_party/mbedtls -Iduckdb/third_party/mbedtls/include -Iduckdb/third_party/mbedtls/library -Iduckdb/third_party/miniz -Iduckdb/third_party/pcg -Iduckdb/third_party/re2 -Iduckdb/third_party/skiplist -Iduckdb/third_party/tdigest -Iduckdb/third_party/utf8proc -Iduckdb/third_party/utf8proc/include -Iduckdb/third_party/yyjson/include -Iduckdb/third_party/zstd/include -Iduckdb/extension/parquet/include -Iduckdb/third_party/parquet -Iduckdb/third_party/thrift -Iduckdb/third_party/lz4 -Iduckdb/third_party/brotli/include -Iduckdb/third_party/brotli/common -Iduckdb/third_party/brotli/dec -Iduckdb/third_party/brotli/enc -Iduckdb/third_party/snappy -Iduckdb/third_party/mbedtls -Iduckdb/third_party/mbedtls/include -Iduckdb/third_party/zstd/include -Iduckdb/extension/core_functions/include -I../inst/include -Iduckdb -DDUCKDB_EXTENSION_PARQUET_LINKED -DDUCKDB_BUILD_LIBRARY -DDUCKDB_EXTENSION_CORE_FUNCTIONS_LINKED -DDUCKDB_BUILD_LIBRARY -OBJECTS=rfuns.o database.o connection.o statement.o register.o relational.o scan.o signal.o transform.o utils.o reltoaltrep.o types.o cpp11.o $(SOURCES) +OBJECTS=rfuns.o database.o connection.o statement.o register.o relational.o scan.o signal.o transform.o utils.o reltoaltrep.o altrepdataframe_relation.o types.o cpp11.o $(SOURCES) diff --git a/src/altrepdataframe_relation.cpp b/src/altrepdataframe_relation.cpp new file mode 100644 index 000000000..c4cc21d44 --- /dev/null +++ b/src/altrepdataframe_relation.cpp @@ -0,0 +1,22 @@ +#include "altrepdataframe_relation.hpp" + +namespace duckdb { + +AltrepDataFrameRelation::AltrepDataFrameRelation(shared_ptr parent) +// TODO: which RelationType should be used? + : Relation(parent->context, RelationType::AGGREGATE_RELATION), parent(std::move(parent)) { +} + +const vector &AltrepDataFrameRelation::Columns() { + return parent->Columns(); +} + +string AltrepDataFrameRelation::ToString(idx_t depth) { + return parent->ToString(depth); +} + +bool AltrepDataFrameRelation::IsReadOnly() { + return parent->IsReadOnly(); +} + +} diff --git a/src/include/altrepdataframe_relation.hpp b/src/include/altrepdataframe_relation.hpp new file mode 100644 index 000000000..a747b2479 --- /dev/null +++ b/src/include/altrepdataframe_relation.hpp @@ -0,0 +1,17 @@ +#include "duckdb/main/relation.hpp" + +namespace duckdb { + +class AltrepDataFrameRelation final : public Relation { +public: + AltrepDataFrameRelation(shared_ptr parent); + + shared_ptr parent; +public: + const vector &Columns() override; + string ToString(idx_t depth) override; + bool IsReadOnly() override; +}; + +} + From c59db7ee82d11827f4eb2f8a3c875fee286f3147 Mon Sep 17 00:00:00 2001 From: Antonov548 Date: Mon, 6 Jan 2025 17:46:20 +0100 Subject: [PATCH 02/69] add `rel_project2` --- R/cpp11.R | 4 ++++ R/relational.R | 13 +++++++++++++ R/rethrow-gen.R | 10 ++++++++++ src/cpp11.cpp | 8 ++++++++ src/relational.cpp | 23 +++++++++++++++++++++++ 5 files changed, 58 insertions(+) diff --git a/R/cpp11.R b/R/cpp11.R index 764ed5b71..c2d723801 100644 --- a/R/cpp11.R +++ b/R/cpp11.R @@ -80,6 +80,10 @@ rapi_rel_filter <- function(rel, exprs) { .Call(`_duckdb_rapi_rel_filter`, rel, exprs) } +rapi_rel_project2 <- function(df, con, exprs) { + .Call(`_duckdb_rapi_rel_project2`, df, con, exprs) +} + rapi_rel_project <- function(rel, exprs) { .Call(`_duckdb_rapi_rel_project`, rel, exprs) } diff --git a/R/relational.R b/R/relational.R index 8d04fc8b1..9ce48a14d 100644 --- a/R/relational.R +++ b/R/relational.R @@ -133,6 +133,19 @@ rel_project <- function(rel, exprs) { rethrow_rapi_rel_project(rel, exprs) } +#' Lazily project a DuckDB relation object +#' @param rel the DuckDB relation object +#' @param exprs a list of DuckDB expressions to project +#' @return the now projected `duckdb_relation` object +#' @noRd +#' @examples +#' con <- DBI::dbConnect(duckdb()) +#' rel <- rel_from_df(con, mtcars) +#' rel2 <- rel_project(rel, list(expr_reference("cyl"), expr_reference("disp"))) +rel_project2 <- function(df, con, exprs) { + rethrow_rapi_rel_project2(as.data.frame(df), con@conn_ref, exprs) +} + #' Lazily filter a DuckDB relation object #' @param rel the DuckDB relation object #' @param exprs a list of DuckDB expressions to filter by diff --git a/R/rethrow-gen.R b/R/rethrow-gen.R index f4a639c2b..a58535ff3 100644 --- a/R/rethrow-gen.R +++ b/R/rethrow-gen.R @@ -189,6 +189,15 @@ rethrow_rapi_rel_project <- function(rel, exprs, call = parent.frame(2)) { ) } +rethrow_rapi_rel_project2 <- function(df, con, exprs, call = parent.frame(2)) { + rlang::try_fetch( + rapi_rel_project2(df, con, exprs), + error = function(e) { + rethrow_error_from_rapi(e, call) + } + ) +} + rethrow_rapi_rel_aggregate <- function(rel, groups, aggregates, call = parent.frame(2)) { rlang::try_fetch( rapi_rel_aggregate(rel, groups, aggregates), @@ -580,6 +589,7 @@ rethrow_restore <- function() { rethrow_rapi_rel_from_df <<- rapi_rel_from_df rethrow_rapi_rel_filter <<- rapi_rel_filter rethrow_rapi_rel_project <<- rapi_rel_project + rethrow_rapi_rel_project2 <<- rapi_rel_project2 rethrow_rapi_rel_aggregate <<- rapi_rel_aggregate rethrow_rapi_rel_order <<- rapi_rel_order rethrow_rapi_expr_window <<- rapi_expr_window diff --git a/src/cpp11.cpp b/src/cpp11.cpp index e1c0649e4..70117e562 100644 --- a/src/cpp11.cpp +++ b/src/cpp11.cpp @@ -154,6 +154,13 @@ extern "C" SEXP _duckdb_rapi_rel_filter(SEXP rel, SEXP exprs) { END_CPP11 } // relational.cpp +SEXP rapi_rel_project2(data_frame df, duckdb::conn_eptr_t con, list exprs); +extern "C" SEXP _duckdb_rapi_rel_project2(SEXP df, SEXP con, SEXP exprs) { + BEGIN_CPP11 + return cpp11::as_sexp(rapi_rel_project2(cpp11::as_cpp>(df), cpp11::as_cpp>(con), cpp11::as_cpp>(exprs))); + END_CPP11 +} +// relational.cpp SEXP rapi_rel_project(duckdb::rel_extptr_t rel, list exprs); extern "C" SEXP _duckdb_rapi_rel_project(SEXP rel, SEXP exprs) { BEGIN_CPP11 @@ -499,6 +506,7 @@ static const R_CallMethodDef CallEntries[] = { {"_duckdb_rapi_rel_names", (DL_FUNC) &_duckdb_rapi_rel_names, 1}, {"_duckdb_rapi_rel_order", (DL_FUNC) &_duckdb_rapi_rel_order, 3}, {"_duckdb_rapi_rel_project", (DL_FUNC) &_duckdb_rapi_rel_project, 2}, + {"_duckdb_rapi_rel_project2", (DL_FUNC) &_duckdb_rapi_rel_project2, 3}, {"_duckdb_rapi_rel_set_alias", (DL_FUNC) &_duckdb_rapi_rel_set_alias, 2}, {"_duckdb_rapi_rel_set_diff", (DL_FUNC) &_duckdb_rapi_rel_set_diff, 2}, {"_duckdb_rapi_rel_set_intersect", (DL_FUNC) &_duckdb_rapi_rel_set_intersect, 2}, diff --git a/src/relational.cpp b/src/relational.cpp index 3642638d7..bfa59550c 100644 --- a/src/relational.cpp +++ b/src/relational.cpp @@ -162,6 +162,29 @@ using namespace cpp11; return make_external_prot("duckdb_relation", prot, res); } +[[cpp11::register]] SEXP rapi_rel_project2(data_frame df, duckdb::conn_eptr_t con, list exprs) { + if (exprs.size() == 0) { + warning("rel_project without projection expressions has no effect"); + return df; + } + vector> projections; + vector aliases; + + for (expr_extptr_t expr : exprs) { + auto dexpr = expr->Copy(); + aliases.push_back(dexpr->GetName()); + projections.push_back(std::move(dexpr)); + } + + duckdb::rel_extptr_t rel = cpp11::as_cpp>(rapi_rel_from_df(con, df, false)); + + auto res = make_shared_ptr(rel->rel, std::move(projections), std::move(aliases)); + + cpp11::writable::list prot = {rel}; + + return make_external_prot("duckdb_relation", prot, res); +} + [[cpp11::register]] SEXP rapi_rel_project(duckdb::rel_extptr_t rel, list exprs) { if (exprs.size() == 0) { warning("rel_project without projection expressions has no effect"); From 65e4a646913a89605feed8566a3a3db54189b142 Mon Sep 17 00:00:00 2001 From: Antonov548 Date: Tue, 7 Jan 2025 10:14:20 +0100 Subject: [PATCH 03/69] stop if no expressions --- src/relational.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/relational.cpp b/src/relational.cpp index bfa59550c..2218d025c 100644 --- a/src/relational.cpp +++ b/src/relational.cpp @@ -164,8 +164,7 @@ using namespace cpp11; [[cpp11::register]] SEXP rapi_rel_project2(data_frame df, duckdb::conn_eptr_t con, list exprs) { if (exprs.size() == 0) { - warning("rel_project without projection expressions has no effect"); - return df; + stop("expected projection expressions"); } vector> projections; vector aliases; From d3a250e4e4282a068a41e7fc10ae63eb2b868d8a Mon Sep 17 00:00:00 2001 From: Antonov548 Date: Tue, 7 Jan 2025 10:16:12 +0100 Subject: [PATCH 04/69] remove `as.data.frame` --- R/relational.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/relational.R b/R/relational.R index 9ce48a14d..0ff570346 100644 --- a/R/relational.R +++ b/R/relational.R @@ -143,7 +143,7 @@ rel_project <- function(rel, exprs) { #' rel <- rel_from_df(con, mtcars) #' rel2 <- rel_project(rel, list(expr_reference("cyl"), expr_reference("disp"))) rel_project2 <- function(df, con, exprs) { - rethrow_rapi_rel_project2(as.data.frame(df), con@conn_ref, exprs) + rethrow_rapi_rel_project2(df, con@conn_ref, exprs) } #' Lazily filter a DuckDB relation object From 45ae5e6ad7ede810b9a98e8807c3685e3439e21d Mon Sep 17 00:00:00 2001 From: Antonov548 Date: Tue, 7 Jan 2025 11:36:01 +0100 Subject: [PATCH 05/69] add `rel_filter2` --- R/cpp11.R | 8 ++++++-- R/relational.R | 16 +++++++++++++++- R/rethrow-gen.R | 10 ++++++++++ src/cpp11.cpp | 14 +++++++++++--- src/relational.cpp | 36 +++++++++++++++++++++++++++++------- 5 files changed, 71 insertions(+), 13 deletions(-) diff --git a/R/cpp11.R b/R/cpp11.R index c2d723801..9e7c9f740 100644 --- a/R/cpp11.R +++ b/R/cpp11.R @@ -80,14 +80,18 @@ rapi_rel_filter <- function(rel, exprs) { .Call(`_duckdb_rapi_rel_filter`, rel, exprs) } -rapi_rel_project2 <- function(df, con, exprs) { - .Call(`_duckdb_rapi_rel_project2`, df, con, exprs) +rapi_rel_filter2 <- function(df, con, exprs) { + .Call(`_duckdb_rapi_rel_filter2`, df, con, exprs) } rapi_rel_project <- function(rel, exprs) { .Call(`_duckdb_rapi_rel_project`, rel, exprs) } +rapi_rel_project2 <- function(df, con, exprs) { + .Call(`_duckdb_rapi_rel_project2`, df, con, exprs) +} + rapi_rel_aggregate <- function(rel, groups, aggregates) { .Call(`_duckdb_rapi_rel_aggregate`, rel, groups, aggregates) } diff --git a/R/relational.R b/R/relational.R index 0ff570346..f63872e29 100644 --- a/R/relational.R +++ b/R/relational.R @@ -143,7 +143,7 @@ rel_project <- function(rel, exprs) { #' rel <- rel_from_df(con, mtcars) #' rel2 <- rel_project(rel, list(expr_reference("cyl"), expr_reference("disp"))) rel_project2 <- function(df, con, exprs) { - rethrow_rapi_rel_project2(df, con@conn_ref, exprs) + rethrow_rapi_rel_project2(as.data.frame(df), con@conn_ref, exprs) } #' Lazily filter a DuckDB relation object @@ -160,6 +160,20 @@ rel_filter <- function(rel, exprs) { rethrow_rapi_rel_filter(rel, exprs) } +#' Lazily filter a DuckDB relation object +#' @param rel the DuckDB relation object +#' @param exprs a list of DuckDB expressions to filter by +#' @return the now filtered `duckdb_relation` object +#' @noRd +#' @examples +#' con <- DBI::dbConnect(duckdb()) +#' DBI::dbExecute(con, "CREATE OR REPLACE MACRO gt(a, b) AS a > b") +#' rel <- rel_from_df(con, mtcars) +#' rel2 <- rel_filter(rel, list(expr_function("gt", list(expr_reference("cyl"), expr_constant("6"))))) +rel_filter2 <- function(df, con, exprs) { + rethrow_rapi_rel_filter2(as.data.frame(df), con@conn_ref, exprs) +} + #' Lazily aggregate a DuckDB relation object #' @param rel the DuckDB relation object #' @param groups a list of DuckDB expressions to group by diff --git a/R/rethrow-gen.R b/R/rethrow-gen.R index a58535ff3..36d1a36aa 100644 --- a/R/rethrow-gen.R +++ b/R/rethrow-gen.R @@ -180,6 +180,15 @@ rethrow_rapi_rel_filter <- function(rel, exprs, call = parent.frame(2)) { ) } +rethrow_rapi_rel_filter2 <- function(df, con, exprs, call = parent.frame(2)) { + rlang::try_fetch( + rapi_rel_filter2(df, con, exprs), + error = function(e) { + rethrow_error_from_rapi(e, call) + } + ) +} + rethrow_rapi_rel_project <- function(rel, exprs, call = parent.frame(2)) { rlang::try_fetch( rapi_rel_project(rel, exprs), @@ -588,6 +597,7 @@ rethrow_restore <- function() { rethrow_rapi_expr_tostring <<- rapi_expr_tostring rethrow_rapi_rel_from_df <<- rapi_rel_from_df rethrow_rapi_rel_filter <<- rapi_rel_filter + rethrow_rapi_rel_filter2 <<- rapi_rel_filter2 rethrow_rapi_rel_project <<- rapi_rel_project rethrow_rapi_rel_project2 <<- rapi_rel_project2 rethrow_rapi_rel_aggregate <<- rapi_rel_aggregate diff --git a/src/cpp11.cpp b/src/cpp11.cpp index 70117e562..6e1e93a10 100644 --- a/src/cpp11.cpp +++ b/src/cpp11.cpp @@ -154,10 +154,10 @@ extern "C" SEXP _duckdb_rapi_rel_filter(SEXP rel, SEXP exprs) { END_CPP11 } // relational.cpp -SEXP rapi_rel_project2(data_frame df, duckdb::conn_eptr_t con, list exprs); -extern "C" SEXP _duckdb_rapi_rel_project2(SEXP df, SEXP con, SEXP exprs) { +SEXP rapi_rel_filter2(data_frame df, duckdb::conn_eptr_t con, list exprs); +extern "C" SEXP _duckdb_rapi_rel_filter2(SEXP df, SEXP con, SEXP exprs) { BEGIN_CPP11 - return cpp11::as_sexp(rapi_rel_project2(cpp11::as_cpp>(df), cpp11::as_cpp>(con), cpp11::as_cpp>(exprs))); + return cpp11::as_sexp(rapi_rel_filter2(cpp11::as_cpp>(df), cpp11::as_cpp>(con), cpp11::as_cpp>(exprs))); END_CPP11 } // relational.cpp @@ -168,6 +168,13 @@ extern "C" SEXP _duckdb_rapi_rel_project(SEXP rel, SEXP exprs) { END_CPP11 } // relational.cpp +SEXP rapi_rel_project2(data_frame df, duckdb::conn_eptr_t con, list exprs); +extern "C" SEXP _duckdb_rapi_rel_project2(SEXP df, SEXP con, SEXP exprs) { + BEGIN_CPP11 + return cpp11::as_sexp(rapi_rel_project2(cpp11::as_cpp>(df), cpp11::as_cpp>(con), cpp11::as_cpp>(exprs))); + END_CPP11 +} +// relational.cpp SEXP rapi_rel_aggregate(duckdb::rel_extptr_t rel, list groups, list aggregates); extern "C" SEXP _duckdb_rapi_rel_aggregate(SEXP rel, SEXP groups, SEXP aggregates) { BEGIN_CPP11 @@ -495,6 +502,7 @@ static const R_CallMethodDef CallEntries[] = { {"_duckdb_rapi_rel_distinct", (DL_FUNC) &_duckdb_rapi_rel_distinct, 1}, {"_duckdb_rapi_rel_explain", (DL_FUNC) &_duckdb_rapi_rel_explain, 3}, {"_duckdb_rapi_rel_filter", (DL_FUNC) &_duckdb_rapi_rel_filter, 2}, + {"_duckdb_rapi_rel_filter2", (DL_FUNC) &_duckdb_rapi_rel_filter2, 3}, {"_duckdb_rapi_rel_from_altrep_df", (DL_FUNC) &_duckdb_rapi_rel_from_altrep_df, 3}, {"_duckdb_rapi_rel_from_df", (DL_FUNC) &_duckdb_rapi_rel_from_df, 3}, {"_duckdb_rapi_rel_from_sql", (DL_FUNC) &_duckdb_rapi_rel_from_sql, 2}, diff --git a/src/relational.cpp b/src/relational.cpp index 2218d025c..aa6251638 100644 --- a/src/relational.cpp +++ b/src/relational.cpp @@ -162,9 +162,32 @@ using namespace cpp11; return make_external_prot("duckdb_relation", prot, res); } -[[cpp11::register]] SEXP rapi_rel_project2(data_frame df, duckdb::conn_eptr_t con, list exprs) { +[[cpp11::register]] SEXP rapi_rel_filter2(data_frame df, duckdb::conn_eptr_t con, list exprs) { + duckdb::unique_ptr filter_expr; + if (exprs.size() == 0) { // nop + stop("expected filter expressions"); + } else if (exprs.size() == 1) { + filter_expr = ((expr_extptr_t)exprs[0])->Copy(); + } else { + vector> filters; + for (expr_extptr_t expr : exprs) { + filters.push_back(expr->Copy()); + } + filter_expr = make_uniq(ExpressionType::CONJUNCTION_AND, std::move(filters)); + } + duckdb::rel_extptr_t rel = cpp11::as_cpp>(rapi_rel_from_df(con, df, false)); + + auto res = make_shared_ptr(rel->rel, std::move(filter_expr)); + + cpp11::writable::list prot = {rel}; + + return make_external_prot("duckdb_relation", prot, res); +} + +[[cpp11::register]] SEXP rapi_rel_project(duckdb::rel_extptr_t rel, list exprs) { if (exprs.size() == 0) { - stop("expected projection expressions"); + warning("rel_project without projection expressions has no effect"); + return rel; } vector> projections; vector aliases; @@ -175,8 +198,6 @@ using namespace cpp11; projections.push_back(std::move(dexpr)); } - duckdb::rel_extptr_t rel = cpp11::as_cpp>(rapi_rel_from_df(con, df, false)); - auto res = make_shared_ptr(rel->rel, std::move(projections), std::move(aliases)); cpp11::writable::list prot = {rel}; @@ -184,10 +205,9 @@ using namespace cpp11; return make_external_prot("duckdb_relation", prot, res); } -[[cpp11::register]] SEXP rapi_rel_project(duckdb::rel_extptr_t rel, list exprs) { +[[cpp11::register]] SEXP rapi_rel_project2(data_frame df, duckdb::conn_eptr_t con, list exprs) { if (exprs.size() == 0) { - warning("rel_project without projection expressions has no effect"); - return rel; + stop("expected projection expressions"); } vector> projections; vector aliases; @@ -198,6 +218,8 @@ using namespace cpp11; projections.push_back(std::move(dexpr)); } + duckdb::rel_extptr_t rel = cpp11::as_cpp>(rapi_rel_from_df(con, df, false)); + auto res = make_shared_ptr(rel->rel, std::move(projections), std::move(aliases)); cpp11::writable::list prot = {rel}; From 7e3bdb84495bc6d2056302728634ff0c12a403fe Mon Sep 17 00:00:00 2001 From: Antonov548 Date: Tue, 7 Jan 2025 14:41:26 +0100 Subject: [PATCH 06/69] fix: remove `as.data.frame` --- R/relational.R | 4 ++-- test-old.R | 43 +++++++++++++++++++++++++++++++++++++++++++ test.R | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 93 insertions(+), 2 deletions(-) create mode 100644 test-old.R create mode 100644 test.R diff --git a/R/relational.R b/R/relational.R index f63872e29..8e6982d23 100644 --- a/R/relational.R +++ b/R/relational.R @@ -143,7 +143,7 @@ rel_project <- function(rel, exprs) { #' rel <- rel_from_df(con, mtcars) #' rel2 <- rel_project(rel, list(expr_reference("cyl"), expr_reference("disp"))) rel_project2 <- function(df, con, exprs) { - rethrow_rapi_rel_project2(as.data.frame(df), con@conn_ref, exprs) + rethrow_rapi_rel_project2(df, con@conn_ref, exprs) } #' Lazily filter a DuckDB relation object @@ -171,7 +171,7 @@ rel_filter <- function(rel, exprs) { #' rel <- rel_from_df(con, mtcars) #' rel2 <- rel_filter(rel, list(expr_function("gt", list(expr_reference("cyl"), expr_constant("6"))))) rel_filter2 <- function(df, con, exprs) { - rethrow_rapi_rel_filter2(as.data.frame(df), con@conn_ref, exprs) + rethrow_rapi_rel_filter2(df, con@conn_ref, exprs) } #' Lazily aggregate a DuckDB relation object diff --git a/test-old.R b/test-old.R new file mode 100644 index 000000000..35a67e97b --- /dev/null +++ b/test-old.R @@ -0,0 +1,43 @@ +drv <- duckdb::duckdb() +con <- DBI::dbConnect(drv) +df1 <- tibble::tibble(a = 1) + +"mutate" +#> [1] "mutate" +rel1 <- duckdb:::rel_from_df(con, df1) +"mutate" +#> [1] "mutate" +rel2 <- duckdb:::rel_project( + rel1, + list( + { + tmp_expr <- duckdb:::expr_reference("a") + duckdb:::expr_set_alias(tmp_expr, "a") + tmp_expr + }, + { + tmp_expr <- duckdb:::expr_constant(2) + duckdb:::expr_set_alias(tmp_expr, "b") + tmp_expr + } + ) +) +"filter" +#> [1] "filter" +rel3 <- duckdb:::rel_filter( + rel2, + list( + duckdb:::expr_comparison( + "==", + list( + duckdb:::expr_reference("b"), + duckdb:::expr_constant(2) + ) + ) + ) +) +rel2 +rel3 +duckdb:::rel_to_altrep(rel2) +rel2 +rel3 diff --git a/test.R b/test.R new file mode 100644 index 000000000..d66dbd44a --- /dev/null +++ b/test.R @@ -0,0 +1,48 @@ +drv <- duckdb::duckdb() +con <- DBI::dbConnect(drv) +df1 <- tibble::tibble(a = 1) + +df1 +"mutate" +rel2 <- duckdb:::rel_project2( + df1, + con, + list( + { + tmp_expr <- duckdb:::expr_reference("a") + duckdb:::expr_set_alias(tmp_expr, "a") + tmp_expr + }, + { + tmp_expr <- duckdb:::expr_constant(2) + duckdb:::expr_set_alias(tmp_expr, "b") + tmp_expr + } + ) +) + +df2 <- duckdb:::rel_to_altrep(rel2) +df1 +df2 +typeof(df1) +typeof(df2) + +"filter" +rel3 <- duckdb:::rel_filter2( + df2, + con, + list( + duckdb:::expr_comparison( + "==", + list( + duckdb:::expr_reference("b"), + duckdb:::expr_constant(2) + ) + ) + ) +) +rel2 +rel3 +duckdb:::rel_to_altrep(rel2) +rel2 +rel3 From ca1ac1723468484ca25269240a44662a2dc2cfba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Tue, 7 Jan 2025 15:08:21 +0100 Subject: [PATCH 07/69] Maybe this -- but doesn't work yet --- src/relational.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/relational.cpp b/src/relational.cpp index aa6251638..03b941598 100644 --- a/src/relational.cpp +++ b/src/relational.cpp @@ -162,6 +162,8 @@ using namespace cpp11; return make_external_prot("duckdb_relation", prot, res); } +SEXP rapi_rel_from_altrep_df(SEXP df, bool strict, bool allow_materialized); + [[cpp11::register]] SEXP rapi_rel_filter2(data_frame df, duckdb::conn_eptr_t con, list exprs) { duckdb::unique_ptr filter_expr; if (exprs.size() == 0) { // nop @@ -175,7 +177,7 @@ using namespace cpp11; } filter_expr = make_uniq(ExpressionType::CONJUNCTION_AND, std::move(filters)); } - duckdb::rel_extptr_t rel = cpp11::as_cpp>(rapi_rel_from_df(con, df, false)); + duckdb::rel_extptr_t rel = cpp11::as_cpp>(rapi_rel_from_altrep_df(df, false, true)); auto res = make_shared_ptr(rel->rel, std::move(filter_expr)); @@ -218,7 +220,7 @@ using namespace cpp11; projections.push_back(std::move(dexpr)); } - duckdb::rel_extptr_t rel = cpp11::as_cpp>(rapi_rel_from_df(con, df, false)); + duckdb::rel_extptr_t rel = cpp11::as_cpp>(rapi_rel_from_altrep_df( df, false, true)); auto res = make_shared_ptr(rel->rel, std::move(projections), std::move(aliases)); From af84bd448b5ed63c70f17b01739481f53513beb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Tue, 7 Jan 2025 15:09:04 +0100 Subject: [PATCH 08/69] Strict --- src/relational.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/relational.cpp b/src/relational.cpp index 03b941598..18e073acd 100644 --- a/src/relational.cpp +++ b/src/relational.cpp @@ -177,7 +177,7 @@ SEXP rapi_rel_from_altrep_df(SEXP df, bool strict, bool allow_materialized); } filter_expr = make_uniq(ExpressionType::CONJUNCTION_AND, std::move(filters)); } - duckdb::rel_extptr_t rel = cpp11::as_cpp>(rapi_rel_from_altrep_df(df, false, true)); + duckdb::rel_extptr_t rel = cpp11::as_cpp>(rapi_rel_from_altrep_df(df, true, true)); auto res = make_shared_ptr(rel->rel, std::move(filter_expr)); @@ -220,7 +220,7 @@ SEXP rapi_rel_from_altrep_df(SEXP df, bool strict, bool allow_materialized); projections.push_back(std::move(dexpr)); } - duckdb::rel_extptr_t rel = cpp11::as_cpp>(rapi_rel_from_altrep_df( df, false, true)); + duckdb::rel_extptr_t rel = cpp11::as_cpp>(rapi_rel_from_altrep_df( df, true, true)); auto res = make_shared_ptr(rel->rel, std::move(projections), std::move(aliases)); From eddf8164ccaf187b33aeebb04f8c16e595b4be6e Mon Sep 17 00:00:00 2001 From: Antonov548 Date: Tue, 7 Jan 2025 19:52:20 +0100 Subject: [PATCH 09/69] add `rapi_rel_from_any_df` --- src/include/rapi.hpp | 2 ++ src/include/reltoaltrep.hpp | 4 ++++ src/relational.cpp | 16 ++++++++++++---- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/include/rapi.hpp b/src/include/rapi.hpp index 50fe9a86b..5c3f0074d 100644 --- a/src/include/rapi.hpp +++ b/src/include/rapi.hpp @@ -220,6 +220,8 @@ SEXP rapi_record_batch(duckdb::rqry_eptr_t, int); cpp11::r_string rapi_ptr_to_str(SEXP extptr); +SEXP rapi_rel_from_df(duckdb::conn_eptr_t con, cpp11::data_frame df, bool experimental); + void duckdb_r_transform(duckdb::Vector &src_vec, SEXP dest, duckdb::idx_t dest_offset, duckdb::idx_t n, bool integer64); SEXP duckdb_r_allocate(const duckdb::LogicalType &type, duckdb::idx_t nrows); void duckdb_r_decorate(const duckdb::LogicalType &type, SEXP dest, bool integer64); diff --git a/src/include/reltoaltrep.hpp b/src/include/reltoaltrep.hpp index 57ede82ad..464971fb7 100644 --- a/src/include/reltoaltrep.hpp +++ b/src/include/reltoaltrep.hpp @@ -27,3 +27,7 @@ struct RelToAltrep { static R_altrep_class_t list_class; #endif }; + +SEXP rapi_rel_from_altrep_df(SEXP df, bool strict, bool allow_materialized); + +SEXP rapi_rel_from_any_df(duckdb::conn_eptr_t con, SEXP df, bool allow_materialized); diff --git a/src/relational.cpp b/src/relational.cpp index 18e073acd..0a7f633ac 100644 --- a/src/relational.cpp +++ b/src/relational.cpp @@ -1,6 +1,7 @@ #include "rapi.hpp" #include "signal.hpp" #include "typesr.hpp" +#include "reltoaltrep.hpp" #include "R_ext/Random.h" @@ -141,6 +142,15 @@ using namespace cpp11; return res; } +SEXP rapi_rel_from_any_df(duckdb::conn_eptr_t con, SEXP df, bool allow_materialized) { + auto rel = rapi_rel_from_altrep_df(df, false, allow_materialized); + if (rel != R_NilValue) { + return rel; + } + + return rapi_rel_from_df(con, df, false); +} + [[cpp11::register]] SEXP rapi_rel_filter(duckdb::rel_extptr_t rel, list exprs) { duckdb::unique_ptr filter_expr; if (exprs.size() == 0) { // nop @@ -162,8 +172,6 @@ using namespace cpp11; return make_external_prot("duckdb_relation", prot, res); } -SEXP rapi_rel_from_altrep_df(SEXP df, bool strict, bool allow_materialized); - [[cpp11::register]] SEXP rapi_rel_filter2(data_frame df, duckdb::conn_eptr_t con, list exprs) { duckdb::unique_ptr filter_expr; if (exprs.size() == 0) { // nop @@ -177,7 +185,7 @@ SEXP rapi_rel_from_altrep_df(SEXP df, bool strict, bool allow_materialized); } filter_expr = make_uniq(ExpressionType::CONJUNCTION_AND, std::move(filters)); } - duckdb::rel_extptr_t rel = cpp11::as_cpp>(rapi_rel_from_altrep_df(df, true, true)); + duckdb::rel_extptr_t rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); auto res = make_shared_ptr(rel->rel, std::move(filter_expr)); @@ -220,7 +228,7 @@ SEXP rapi_rel_from_altrep_df(SEXP df, bool strict, bool allow_materialized); projections.push_back(std::move(dexpr)); } - duckdb::rel_extptr_t rel = cpp11::as_cpp>(rapi_rel_from_altrep_df( df, true, true)); + duckdb::rel_extptr_t rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); auto res = make_shared_ptr(rel->rel, std::move(projections), std::move(aliases)); From 889af85911782c21738284e5fe3227689a898993 Mon Sep 17 00:00:00 2001 From: Antonov548 Date: Wed, 8 Jan 2025 12:21:10 +0100 Subject: [PATCH 10/69] use `AltrepDataFrameRelation` --- src/altrepdataframe_relation.cpp | 7 ++++++- src/include/altrepdataframe_relation.hpp | 4 +++- src/relational.cpp | 9 +++++++-- src/reltoaltrep.cpp | 2 +- 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/altrepdataframe_relation.cpp b/src/altrepdataframe_relation.cpp index c4cc21d44..af8250029 100644 --- a/src/altrepdataframe_relation.cpp +++ b/src/altrepdataframe_relation.cpp @@ -5,10 +5,11 @@ namespace duckdb { AltrepDataFrameRelation::AltrepDataFrameRelation(shared_ptr parent) // TODO: which RelationType should be used? : Relation(parent->context, RelationType::AGGREGATE_RELATION), parent(std::move(parent)) { + TryBindRelation(columns); } const vector &AltrepDataFrameRelation::Columns() { - return parent->Columns(); + return columns; } string AltrepDataFrameRelation::ToString(idx_t depth) { @@ -19,4 +20,8 @@ bool AltrepDataFrameRelation::IsReadOnly() { return parent->IsReadOnly(); } +unique_ptr AltrepDataFrameRelation::GetQueryNode() { + return parent->GetQueryNode(); +} + } diff --git a/src/include/altrepdataframe_relation.hpp b/src/include/altrepdataframe_relation.hpp index a747b2479..b149c8d92 100644 --- a/src/include/altrepdataframe_relation.hpp +++ b/src/include/altrepdataframe_relation.hpp @@ -7,11 +7,13 @@ class AltrepDataFrameRelation final : public Relation { AltrepDataFrameRelation(shared_ptr parent); shared_ptr parent; + vector columns; public: + unique_ptr GetQueryNode() override; + const vector &Columns() override; string ToString(idx_t depth) override; bool IsReadOnly() override; }; } - diff --git a/src/relational.cpp b/src/relational.cpp index 0a7f633ac..d788c90fc 100644 --- a/src/relational.cpp +++ b/src/relational.cpp @@ -2,6 +2,7 @@ #include "signal.hpp" #include "typesr.hpp" #include "reltoaltrep.hpp" +#include "altrepdataframe_relation.hpp" #include "R_ext/Random.h" @@ -187,7 +188,9 @@ SEXP rapi_rel_from_any_df(duckdb::conn_eptr_t con, SEXP df, bool allow_materiali } duckdb::rel_extptr_t rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); - auto res = make_shared_ptr(rel->rel, std::move(filter_expr)); + auto filter = make_shared_ptr(rel->rel, std::move(filter_expr)); + + auto res = make_shared_ptr(filter); cpp11::writable::list prot = {rel}; @@ -230,7 +233,9 @@ SEXP rapi_rel_from_any_df(duckdb::conn_eptr_t con, SEXP df, bool allow_materiali duckdb::rel_extptr_t rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); - auto res = make_shared_ptr(rel->rel, std::move(projections), std::move(aliases)); + auto projection = make_shared_ptr(rel->rel, std::move(projections), std::move(aliases)); + + auto res = make_shared_ptr(projection); cpp11::writable::list prot = {rel}; diff --git a/src/reltoaltrep.cpp b/src/reltoaltrep.cpp index d5d9faa3f..2c72bb64e 100644 --- a/src/reltoaltrep.cpp +++ b/src/reltoaltrep.cpp @@ -114,7 +114,7 @@ struct AltrepRelationWrapper { } auto materialize_message = Rf_GetOption(RStrings::get().materialize_message_sym, R_BaseEnv); - if (Rf_isLogical(materialize_message) && Rf_length(materialize_message) == 1 && LOGICAL_ELT(materialize_message, 0) == true) { + if (Rf_isLogical(materialize_message) && Rf_length(materialize_message) == 1 && LOGICAL_ELT(materialize_message, 0) == true) { // Legacy Rprintf("duckplyr: materializing\n"); } From 32a0eb836c3892f719eae3b7770d911196319e28 Mon Sep 17 00:00:00 2001 From: Antonov548 Date: Thu, 9 Jan 2025 14:08:38 +0100 Subject: [PATCH 11/69] add `EXTENSION_RELATION` type --- src/duckdb/src/common/enum_util.cpp | 7 ++++--- src/duckdb/src/common/enums/relation_type.cpp | 2 ++ .../src/include/duckdb/common/enums/relation_type.hpp | 3 ++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/duckdb/src/common/enum_util.cpp b/src/duckdb/src/common/enum_util.cpp index 23d9c6e27..a03b33d63 100644 --- a/src/duckdb/src/common/enum_util.cpp +++ b/src/duckdb/src/common/enum_util.cpp @@ -3034,19 +3034,20 @@ const StringUtil::EnumStringLiteral *GetRelationTypeValues() { { static_cast(RelationType::VIEW_RELATION), "VIEW_RELATION" }, { static_cast(RelationType::QUERY_RELATION), "QUERY_RELATION" }, { static_cast(RelationType::DELIM_JOIN_RELATION), "DELIM_JOIN_RELATION" }, - { static_cast(RelationType::DELIM_GET_RELATION), "DELIM_GET_RELATION" } + { static_cast(RelationType::DELIM_GET_RELATION), "DELIM_GET_RELATION" }, + { static_cast(RelationType::EXTENSION_RELATION), "EXTENSION_RELATION" } }; return values; } template<> const char* EnumUtil::ToChars(RelationType value) { - return StringUtil::EnumToString(GetRelationTypeValues(), 28, "RelationType", static_cast(value)); + return StringUtil::EnumToString(GetRelationTypeValues(), 29, "RelationType", static_cast(value)); } template<> RelationType EnumUtil::FromString(const char *value) { - return static_cast(StringUtil::StringToEnum(GetRelationTypeValues(), 28, "RelationType", value)); + return static_cast(StringUtil::StringToEnum(GetRelationTypeValues(), 29, "RelationType", value)); } const StringUtil::EnumStringLiteral *GetRenderModeValues() { diff --git a/src/duckdb/src/common/enums/relation_type.cpp b/src/duckdb/src/common/enums/relation_type.cpp index 4f58ed7c4..dc02b8970 100644 --- a/src/duckdb/src/common/enums/relation_type.cpp +++ b/src/duckdb/src/common/enums/relation_type.cpp @@ -61,6 +61,8 @@ string RelationTypeToString(RelationType type) { return "VIEW_RELATION"; case RelationType::QUERY_RELATION: return "QUERY_RELATION"; + case RelationType::EXTENSION_RELATION: + return "EXTENSION_RELATION"; case RelationType::INVALID_RELATION: break; } diff --git a/src/duckdb/src/include/duckdb/common/enums/relation_type.hpp b/src/duckdb/src/include/duckdb/common/enums/relation_type.hpp index 302b2f369..bca6af491 100644 --- a/src/duckdb/src/include/duckdb/common/enums/relation_type.hpp +++ b/src/duckdb/src/include/duckdb/common/enums/relation_type.hpp @@ -43,7 +43,8 @@ enum class RelationType : uint8_t { VIEW_RELATION, QUERY_RELATION, DELIM_JOIN_RELATION, - DELIM_GET_RELATION + DELIM_GET_RELATION, + EXTENSION_RELATION = 255 }; string RelationTypeToString(RelationType type); From 5a8961043790026ac5a280c269f90cadc9e7b3a3 Mon Sep 17 00:00:00 2001 From: Antonov548 Date: Thu, 9 Jan 2025 14:09:18 +0100 Subject: [PATCH 12/69] change `rapi_rel_to_altrep` to handle df --- src/altrepdataframe_relation.cpp | 39 ++++++-- src/cpp11.cpp | 8 +- src/include/altrepdataframe_relation.hpp | 15 ++- src/include/reltoaltrep.hpp | 22 +++++ src/relational.cpp | 8 +- src/reltoaltrep.cpp | 113 +++++++++++------------ 6 files changed, 127 insertions(+), 78 deletions(-) diff --git a/src/altrepdataframe_relation.cpp b/src/altrepdataframe_relation.cpp index af8250029..999748d40 100644 --- a/src/altrepdataframe_relation.cpp +++ b/src/altrepdataframe_relation.cpp @@ -1,10 +1,15 @@ #include "altrepdataframe_relation.hpp" +#include "R_ext/Random.h" + namespace duckdb { -AltrepDataFrameRelation::AltrepDataFrameRelation(shared_ptr parent) -// TODO: which RelationType should be used? - : Relation(parent->context, RelationType::AGGREGATE_RELATION), parent(std::move(parent)) { +AltrepDataFrameRelation::AltrepDataFrameRelation(duckdb::shared_ptr p, cpp11::sexp df, duckdb::conn_eptr_t con, duckdb::shared_ptr altrep) + : Relation(p->context, RelationType::EXTENSION_RELATION) + , altrep(std::move(altrep)) + , dataframe(df) + , connection(std::move(con)) + , parent(std::move(p)) { TryBindRelation(columns); } @@ -13,15 +18,37 @@ const vector &AltrepDataFrameRelation::Columns() { } string AltrepDataFrameRelation::ToString(idx_t depth) { - return parent->ToString(depth); + return GetParent().ToString(depth); } bool AltrepDataFrameRelation::IsReadOnly() { - return parent->IsReadOnly(); + return GetParent().IsReadOnly(); } unique_ptr AltrepDataFrameRelation::GetQueryNode() { - return parent->GetQueryNode(); + return GetParent().GetQueryNode(); +} + +Relation& AltrepDataFrameRelation::GetParent() { + if (altrep->HasQueryResult()) { + // here context mutex locked + return GetTableRelation(); + } else { + return *parent; + } +} + +Relation& AltrepDataFrameRelation::GetTableRelation() { + if (!table_function_relation) { + named_parameter_map_t other_params; + other_params["experimental"] = Value::BOOLEAN(false); + auto alias = StringUtil::Format("dataframe_%d_%d", (uintptr_t)(SEXP)dataframe, + (int32_t)(NumericLimits::Maximum() * unif_rand())); + + table_function_relation = connection->conn->TableFunction("r_dataframe_scan", {Value::POINTER((uintptr_t)(SEXP)dataframe)}, other_params)->Alias(alias); + } + + return *table_function_relation; } } diff --git a/src/cpp11.cpp b/src/cpp11.cpp index 6e1e93a10..58c2ae4df 100644 --- a/src/cpp11.cpp +++ b/src/cpp11.cpp @@ -361,10 +361,10 @@ extern "C" SEXP _duckdb_rapi_rel_insert(SEXP rel, SEXP schema_name, SEXP table_n END_CPP11 } // reltoaltrep.cpp -SEXP rapi_rel_to_altrep(duckdb::rel_extptr_t rel, bool allow_materialization); -extern "C" SEXP _duckdb_rapi_rel_to_altrep(SEXP rel, SEXP allow_materialization) { +SEXP rapi_rel_to_altrep(duckdb::rel_extptr_t rel, duckdb::conn_eptr_t con, bool allow_materialization); +extern "C" SEXP _duckdb_rapi_rel_to_altrep(SEXP rel, SEXP con, SEXP allow_materialization) { BEGIN_CPP11 - return cpp11::as_sexp(rapi_rel_to_altrep(cpp11::as_cpp>(rel), cpp11::as_cpp>(allow_materialization))); + return cpp11::as_sexp(rapi_rel_to_altrep(cpp11::as_cpp>(rel), cpp11::as_cpp>(con), cpp11::as_cpp>(allow_materialization))); END_CPP11 } // reltoaltrep.cpp @@ -520,7 +520,7 @@ static const R_CallMethodDef CallEntries[] = { {"_duckdb_rapi_rel_set_intersect", (DL_FUNC) &_duckdb_rapi_rel_set_intersect, 2}, {"_duckdb_rapi_rel_set_symdiff", (DL_FUNC) &_duckdb_rapi_rel_set_symdiff, 2}, {"_duckdb_rapi_rel_sql", (DL_FUNC) &_duckdb_rapi_rel_sql, 2}, - {"_duckdb_rapi_rel_to_altrep", (DL_FUNC) &_duckdb_rapi_rel_to_altrep, 2}, + {"_duckdb_rapi_rel_to_altrep", (DL_FUNC) &_duckdb_rapi_rel_to_altrep, 3}, {"_duckdb_rapi_rel_to_csv", (DL_FUNC) &_duckdb_rapi_rel_to_csv, 3}, {"_duckdb_rapi_rel_to_df", (DL_FUNC) &_duckdb_rapi_rel_to_df, 1}, {"_duckdb_rapi_rel_to_parquet", (DL_FUNC) &_duckdb_rapi_rel_to_parquet, 3}, diff --git a/src/include/altrepdataframe_relation.hpp b/src/include/altrepdataframe_relation.hpp index b149c8d92..b04bb02ea 100644 --- a/src/include/altrepdataframe_relation.hpp +++ b/src/include/altrepdataframe_relation.hpp @@ -1,12 +1,18 @@ #include "duckdb/main/relation.hpp" +#include "rapi.hpp" +#include "reltoaltrep.hpp" namespace duckdb { class AltrepDataFrameRelation final : public Relation { public: - AltrepDataFrameRelation(shared_ptr parent); + AltrepDataFrameRelation(duckdb::shared_ptr p, cpp11::sexp df, duckdb::conn_eptr_t con, duckdb::shared_ptr altrep); - shared_ptr parent; + shared_ptr table_function_relation; + cpp11::sexp dataframe; + duckdb::conn_eptr_t connection; + duckdb::shared_ptr altrep; + duckdb::shared_ptr parent; vector columns; public: unique_ptr GetQueryNode() override; @@ -14,6 +20,11 @@ class AltrepDataFrameRelation final : public Relation { const vector &Columns() override; string ToString(idx_t depth) override; bool IsReadOnly() override; + +private: + Relation& GetTableRelation(); + + Relation& GetParent(); }; } diff --git a/src/include/reltoaltrep.hpp b/src/include/reltoaltrep.hpp index 464971fb7..189dbbe0a 100644 --- a/src/include/reltoaltrep.hpp +++ b/src/include/reltoaltrep.hpp @@ -2,6 +2,26 @@ #include "rapi.hpp" +namespace duckdb { + +struct AltrepRelationWrapper { + AltrepRelationWrapper(rel_extptr_t rel_, bool allow_materialization_); + + static AltrepRelationWrapper *Get(SEXP x); + + bool HasQueryResult() const; + + MaterializedQueryResult *GetQueryResult(); + + bool allow_materialization; + + rel_extptr_t rel_eptr; + duckdb::shared_ptr rel; + duckdb::unique_ptr res; +}; + +} + struct RelToAltrep { static void Initialize(DllInfo *dll); static R_xlen_t RownamesLength(SEXP x); @@ -31,3 +51,5 @@ struct RelToAltrep { SEXP rapi_rel_from_altrep_df(SEXP df, bool strict, bool allow_materialized); SEXP rapi_rel_from_any_df(duckdb::conn_eptr_t con, SEXP df, bool allow_materialized); + +SEXP rapi_rel_to_altrep(duckdb::rel_extptr_t rel, duckdb::conn_eptr_t con, bool allow_materialization); diff --git a/src/relational.cpp b/src/relational.cpp index d788c90fc..9c386be83 100644 --- a/src/relational.cpp +++ b/src/relational.cpp @@ -190,11 +190,9 @@ SEXP rapi_rel_from_any_df(duckdb::conn_eptr_t con, SEXP df, bool allow_materiali auto filter = make_shared_ptr(rel->rel, std::move(filter_expr)); - auto res = make_shared_ptr(filter); - cpp11::writable::list prot = {rel}; - return make_external_prot("duckdb_relation", prot, res); + return rapi_rel_to_altrep(make_external_prot("duckdb_relation", prot, filter), con, true); } [[cpp11::register]] SEXP rapi_rel_project(duckdb::rel_extptr_t rel, list exprs) { @@ -235,11 +233,9 @@ SEXP rapi_rel_from_any_df(duckdb::conn_eptr_t con, SEXP df, bool allow_materiali auto projection = make_shared_ptr(rel->rel, std::move(projections), std::move(aliases)); - auto res = make_shared_ptr(projection); - cpp11::writable::list prot = {rel}; - return make_external_prot("duckdb_relation", prot, res); + return rapi_rel_to_altrep(make_external_prot("duckdb_relation", prot, projection), con, true); } [[cpp11::register]] SEXP rapi_rel_aggregate(duckdb::rel_extptr_t rel, list groups, list aggregates) { diff --git a/src/reltoaltrep.cpp b/src/reltoaltrep.cpp index 2c72bb64e..a19ae0e13 100644 --- a/src/reltoaltrep.cpp +++ b/src/reltoaltrep.cpp @@ -5,6 +5,7 @@ #include "reltoaltrep.hpp" #include "signal.hpp" #include "cpp11/declarations.hpp" +#include "altrepdataframe_relation.hpp" #include "httplib.hpp" #include @@ -87,78 +88,69 @@ static T *GetFromExternalPtr(SEXP x) { return wrapper; } -struct AltrepRelationWrapper { - - static AltrepRelationWrapper *Get(SEXP x) { - return GetFromExternalPtr(x); - } +AltrepRelationWrapper *AltrepRelationWrapper::Get(SEXP x) { + return GetFromExternalPtr(x); +} - AltrepRelationWrapper(rel_extptr_t rel_, bool allow_materialization_) - : allow_materialization(allow_materialization_), rel_eptr(rel_), rel(rel_->rel) { - } +AltrepRelationWrapper::AltrepRelationWrapper(rel_extptr_t rel_, bool allow_materialization_) + : allow_materialization(allow_materialization_), rel_eptr(rel_), rel(rel_->rel) { +} - bool HasQueryResult() const { - return (bool)res; - } +bool AltrepRelationWrapper::HasQueryResult() const { + return (bool)res; +} - MaterializedQueryResult *GetQueryResult() { - if (!res) { - if (!allow_materialization) { - cpp11::stop("Materialization is disabled, use collect() or as_tibble() to materialize"); - } +MaterializedQueryResult *AltrepRelationWrapper::GetQueryResult() { + if (!res) { + if (!allow_materialization) { + cpp11::stop("Materialization is disabled, use collect() or as_tibble() to materialize"); + } - auto materialize_callback = Rf_GetOption(RStrings::get().materialize_callback_sym, R_BaseEnv); - if (Rf_isFunction(materialize_callback)) { - sexp call = Rf_lang2(materialize_callback, rel_eptr); - Rf_eval(call, R_BaseEnv); - } + auto materialize_callback = Rf_GetOption(RStrings::get().materialize_callback_sym, R_BaseEnv); + if (Rf_isFunction(materialize_callback)) { + sexp call = Rf_lang2(materialize_callback, rel_eptr); + Rf_eval(call, R_BaseEnv); + } - auto materialize_message = Rf_GetOption(RStrings::get().materialize_message_sym, R_BaseEnv); - if (Rf_isLogical(materialize_message) && Rf_length(materialize_message) == 1 && LOGICAL_ELT(materialize_message, 0) == true) { - // Legacy - Rprintf("duckplyr: materializing\n"); - } + auto materialize_message = Rf_GetOption(RStrings::get().materialize_message_sym, R_BaseEnv); + if (Rf_isLogical(materialize_message) && Rf_length(materialize_message) == 1 && LOGICAL_ELT(materialize_message, 0) == true) { + // Legacy + Rprintf("duckplyr: materializing\n"); + } - ScopedInterruptHandler signal_handler(rel->context->GetContext()); + ScopedInterruptHandler signal_handler(rel->context->GetContext()); - // We need to temporarily allow a deeper execution stack - // https://github.com/duckdb/duckdb-r/issues/101 - auto old_depth = rel->context->GetContext()->config.max_expression_depth; - rel->context->GetContext()->config.max_expression_depth = old_depth * 2; - duckdb_httplib::detail::scope_exit reset_max_expression_depth( - [&]() { rel->context->GetContext()->config.max_expression_depth = old_depth; }); + // We need to temporarily allow a deeper execution stack + // https://github.com/duckdb/duckdb-r/issues/101 + auto old_depth = rel->context->GetContext()->config.max_expression_depth; + rel->context->GetContext()->config.max_expression_depth = old_depth * 2; + duckdb_httplib::detail::scope_exit reset_max_expression_depth( + [&]() { rel->context->GetContext()->config.max_expression_depth = old_depth; }); - res = rel->Execute(); + res = rel->Execute(); - // FIXME: Use std::experimental::scope_exit - if (rel->context->GetContext()->config.max_expression_depth != old_depth * 2) { - Rprintf("Internal error: max_expression_depth was changed from %" PRIu64 " to %" PRIu64 "\n", - old_depth * 2, rel->context->GetContext()->config.max_expression_depth); - } - rel->context->GetContext()->config.max_expression_depth = old_depth; - reset_max_expression_depth.release(); + // FIXME: Use std::experimental::scope_exit + if (rel->context->GetContext()->config.max_expression_depth != old_depth * 2) { + Rprintf("Internal error: max_expression_depth was changed from %" PRIu64 " to %" PRIu64 "\n", + old_depth * 2, rel->context->GetContext()->config.max_expression_depth); + } + rel->context->GetContext()->config.max_expression_depth = old_depth; + reset_max_expression_depth.release(); - if (signal_handler.HandleInterrupt()) { - cpp11::stop("Query execution was interrupted"); - } + if (signal_handler.HandleInterrupt()) { + cpp11::stop("Query execution was interrupted"); + } - signal_handler.Disable(); + signal_handler.Disable(); - if (res->HasError()) { - cpp11::stop("Error evaluating duckdb query: %s", res->GetError().c_str()); - } - D_ASSERT(res->type == QueryResultType::MATERIALIZED_RESULT); + if (res->HasError()) { + cpp11::stop("Error evaluating duckdb query: %s", res->GetError().c_str()); } - D_ASSERT(res); - return (MaterializedQueryResult *)res.get(); + D_ASSERT(res->type == QueryResultType::MATERIALIZED_RESULT); } - - bool allow_materialization; - - rel_extptr_t rel_eptr; - duckdb::shared_ptr rel; - duckdb::unique_ptr res; -}; + D_ASSERT(res); + return (MaterializedQueryResult *)res.get(); +} struct AltrepRownamesWrapper { @@ -348,7 +340,7 @@ static R_altrep_class_t LogicalTypeToAltrepType(const LogicalType &type) { } } -[[cpp11::register]] SEXP rapi_rel_to_altrep(duckdb::rel_extptr_t rel, bool allow_materialization) { +[[cpp11::register]] SEXP rapi_rel_to_altrep(duckdb::rel_extptr_t rel, duckdb::conn_eptr_t con, bool allow_materialization) { D_ASSERT(rel && rel->rel); auto drel = rel->rel; auto ncols = drel->Columns().size(); @@ -381,7 +373,8 @@ static R_altrep_class_t LogicalTypeToAltrepType(const LogicalType &type) { // Row names cpp11::external_pointer ptr(new AltrepRownamesWrapper(relation_wrapper)); R_SetExternalPtrTag(ptr, RStrings::get().duckdb_row_names_sym); - cpp11::sexp row_names_sexp = R_new_altrep(RelToAltrep::rownames_class, ptr, rel); + cpp11::sexp row_names_sexp = R_new_altrep(RelToAltrep::rownames_class, ptr, make_external("duckdb_relation", + make_shared_ptr(rel->rel, data_frame, con, relation_wrapper))); install_new_attrib(data_frame, R_RowNamesSymbol, row_names_sexp); // Class From 2a0c3449ab5ac7ccde77bc0d8d0128ce3fe8b8a1 Mon Sep 17 00:00:00 2001 From: Antonov548 Date: Thu, 9 Jan 2025 15:02:52 +0100 Subject: [PATCH 13/69] add connection --- R/cpp11.R | 4 ++-- R/cpp12.R | 4 ++-- R/relational.R | 4 ++-- R/rethrow-gen.R | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/R/cpp11.R b/R/cpp11.R index 9e7c9f740..6ed7648b7 100644 --- a/R/cpp11.R +++ b/R/cpp11.R @@ -196,8 +196,8 @@ rapi_rel_insert <- function(rel, schema_name, table_name) { invisible(.Call(`_duckdb_rapi_rel_insert`, rel, schema_name, table_name)) } -rapi_rel_to_altrep <- function(rel, allow_materialization) { - .Call(`_duckdb_rapi_rel_to_altrep`, rel, allow_materialization) +rapi_rel_to_altrep <- function(rel, con, allow_materialization) { + .Call(`_duckdb_rapi_rel_to_altrep`, rel, con, allow_materialization) } rapi_rel_from_altrep_df <- function(df, strict, allow_materialized) { diff --git a/R/cpp12.R b/R/cpp12.R index b5e8e882c..0db34c931 100644 --- a/R/cpp12.R +++ b/R/cpp12.R @@ -1,4 +1,4 @@ # allow_materialization = TRUE: compatibility with duckplyr <= 0.4.1 -rapi_rel_to_altrep <- function(rel, allow_materialization = TRUE) { - .Call(`_duckdb_rapi_rel_to_altrep`, rel, allow_materialization) +rapi_rel_to_altrep <- function(rel, conn, allow_materialization = TRUE) { + .Call(`_duckdb_rapi_rel_to_altrep`, rel, conn, allow_materialization) } diff --git a/R/relational.R b/R/relational.R index 8e6982d23..0f2ca237b 100644 --- a/R/relational.R +++ b/R/relational.R @@ -439,8 +439,8 @@ rel_set_alias <- function(rel, alias) { #' con <- DBI::dbConnect(duckdb()) #' rel <- rel_from_df(con, mtcars) #' print(rel_to_altrep(rel)) -rel_to_altrep <- function(rel, allow_materialization = TRUE) { - rethrow_rapi_rel_to_altrep(rel, allow_materialization) +rel_to_altrep <- function(rel, con, allow_materialization = TRUE) { + rethrow_rapi_rel_to_altrep(rel, con@conn_ref, allow_materialization) } diff --git a/R/rethrow-gen.R b/R/rethrow-gen.R index 36d1a36aa..611d64a93 100644 --- a/R/rethrow-gen.R +++ b/R/rethrow-gen.R @@ -441,9 +441,9 @@ rethrow_rapi_rel_insert <- function(rel, schema_name, table_name, call = parent. ) } -rethrow_rapi_rel_to_altrep <- function(rel, allow_materialization, call = parent.frame(2)) { +rethrow_rapi_rel_to_altrep <- function(rel, conn, allow_materialization, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_to_altrep(rel, allow_materialization), + rapi_rel_to_altrep(rel, conn, allow_materialization), error = function(e) { rethrow_error_from_rapi(e, call) } From 4d8b8479fc27f13675d81460a3d9266cd83b1644 Mon Sep 17 00:00:00 2001 From: Antonov548 Date: Thu, 9 Jan 2025 16:48:58 +0100 Subject: [PATCH 14/69] add rapi_rel_to_altrep2 --- R/cpp11.R | 4 ++-- R/cpp12.R | 4 ++-- R/relational.R | 2 +- R/rethrow-gen.R | 4 ++-- src/cpp11.cpp | 8 +++---- src/include/reltoaltrep.hpp | 2 +- src/relational.cpp | 4 ++-- src/reltoaltrep.cpp | 45 ++++++++++++++++++++++++++++++++++++- 8 files changed, 58 insertions(+), 15 deletions(-) diff --git a/R/cpp11.R b/R/cpp11.R index 6ed7648b7..9e7c9f740 100644 --- a/R/cpp11.R +++ b/R/cpp11.R @@ -196,8 +196,8 @@ rapi_rel_insert <- function(rel, schema_name, table_name) { invisible(.Call(`_duckdb_rapi_rel_insert`, rel, schema_name, table_name)) } -rapi_rel_to_altrep <- function(rel, con, allow_materialization) { - .Call(`_duckdb_rapi_rel_to_altrep`, rel, con, allow_materialization) +rapi_rel_to_altrep <- function(rel, allow_materialization) { + .Call(`_duckdb_rapi_rel_to_altrep`, rel, allow_materialization) } rapi_rel_from_altrep_df <- function(df, strict, allow_materialized) { diff --git a/R/cpp12.R b/R/cpp12.R index 0db34c931..b5e8e882c 100644 --- a/R/cpp12.R +++ b/R/cpp12.R @@ -1,4 +1,4 @@ # allow_materialization = TRUE: compatibility with duckplyr <= 0.4.1 -rapi_rel_to_altrep <- function(rel, conn, allow_materialization = TRUE) { - .Call(`_duckdb_rapi_rel_to_altrep`, rel, conn, allow_materialization) +rapi_rel_to_altrep <- function(rel, allow_materialization = TRUE) { + .Call(`_duckdb_rapi_rel_to_altrep`, rel, allow_materialization) } diff --git a/R/relational.R b/R/relational.R index 0f2ca237b..5fa1a61c4 100644 --- a/R/relational.R +++ b/R/relational.R @@ -440,7 +440,7 @@ rel_set_alias <- function(rel, alias) { #' rel <- rel_from_df(con, mtcars) #' print(rel_to_altrep(rel)) rel_to_altrep <- function(rel, con, allow_materialization = TRUE) { - rethrow_rapi_rel_to_altrep(rel, con@conn_ref, allow_materialization) + rethrow_rapi_rel_to_altrep(rel, allow_materialization) } diff --git a/R/rethrow-gen.R b/R/rethrow-gen.R index 611d64a93..36d1a36aa 100644 --- a/R/rethrow-gen.R +++ b/R/rethrow-gen.R @@ -441,9 +441,9 @@ rethrow_rapi_rel_insert <- function(rel, schema_name, table_name, call = parent. ) } -rethrow_rapi_rel_to_altrep <- function(rel, conn, allow_materialization, call = parent.frame(2)) { +rethrow_rapi_rel_to_altrep <- function(rel, allow_materialization, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_to_altrep(rel, conn, allow_materialization), + rapi_rel_to_altrep(rel, allow_materialization), error = function(e) { rethrow_error_from_rapi(e, call) } diff --git a/src/cpp11.cpp b/src/cpp11.cpp index 58c2ae4df..6e1e93a10 100644 --- a/src/cpp11.cpp +++ b/src/cpp11.cpp @@ -361,10 +361,10 @@ extern "C" SEXP _duckdb_rapi_rel_insert(SEXP rel, SEXP schema_name, SEXP table_n END_CPP11 } // reltoaltrep.cpp -SEXP rapi_rel_to_altrep(duckdb::rel_extptr_t rel, duckdb::conn_eptr_t con, bool allow_materialization); -extern "C" SEXP _duckdb_rapi_rel_to_altrep(SEXP rel, SEXP con, SEXP allow_materialization) { +SEXP rapi_rel_to_altrep(duckdb::rel_extptr_t rel, bool allow_materialization); +extern "C" SEXP _duckdb_rapi_rel_to_altrep(SEXP rel, SEXP allow_materialization) { BEGIN_CPP11 - return cpp11::as_sexp(rapi_rel_to_altrep(cpp11::as_cpp>(rel), cpp11::as_cpp>(con), cpp11::as_cpp>(allow_materialization))); + return cpp11::as_sexp(rapi_rel_to_altrep(cpp11::as_cpp>(rel), cpp11::as_cpp>(allow_materialization))); END_CPP11 } // reltoaltrep.cpp @@ -520,7 +520,7 @@ static const R_CallMethodDef CallEntries[] = { {"_duckdb_rapi_rel_set_intersect", (DL_FUNC) &_duckdb_rapi_rel_set_intersect, 2}, {"_duckdb_rapi_rel_set_symdiff", (DL_FUNC) &_duckdb_rapi_rel_set_symdiff, 2}, {"_duckdb_rapi_rel_sql", (DL_FUNC) &_duckdb_rapi_rel_sql, 2}, - {"_duckdb_rapi_rel_to_altrep", (DL_FUNC) &_duckdb_rapi_rel_to_altrep, 3}, + {"_duckdb_rapi_rel_to_altrep", (DL_FUNC) &_duckdb_rapi_rel_to_altrep, 2}, {"_duckdb_rapi_rel_to_csv", (DL_FUNC) &_duckdb_rapi_rel_to_csv, 3}, {"_duckdb_rapi_rel_to_df", (DL_FUNC) &_duckdb_rapi_rel_to_df, 1}, {"_duckdb_rapi_rel_to_parquet", (DL_FUNC) &_duckdb_rapi_rel_to_parquet, 3}, diff --git a/src/include/reltoaltrep.hpp b/src/include/reltoaltrep.hpp index 189dbbe0a..485016cd7 100644 --- a/src/include/reltoaltrep.hpp +++ b/src/include/reltoaltrep.hpp @@ -52,4 +52,4 @@ SEXP rapi_rel_from_altrep_df(SEXP df, bool strict, bool allow_materialized); SEXP rapi_rel_from_any_df(duckdb::conn_eptr_t con, SEXP df, bool allow_materialized); -SEXP rapi_rel_to_altrep(duckdb::rel_extptr_t rel, duckdb::conn_eptr_t con, bool allow_materialization); +SEXP rapi_rel_to_altrep2(duckdb::rel_extptr_t rel, duckdb::conn_eptr_t con, bool allow_materialization); diff --git a/src/relational.cpp b/src/relational.cpp index 9c386be83..c2810aa47 100644 --- a/src/relational.cpp +++ b/src/relational.cpp @@ -192,7 +192,7 @@ SEXP rapi_rel_from_any_df(duckdb::conn_eptr_t con, SEXP df, bool allow_materiali cpp11::writable::list prot = {rel}; - return rapi_rel_to_altrep(make_external_prot("duckdb_relation", prot, filter), con, true); + return rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, filter), con, true); } [[cpp11::register]] SEXP rapi_rel_project(duckdb::rel_extptr_t rel, list exprs) { @@ -235,7 +235,7 @@ SEXP rapi_rel_from_any_df(duckdb::conn_eptr_t con, SEXP df, bool allow_materiali cpp11::writable::list prot = {rel}; - return rapi_rel_to_altrep(make_external_prot("duckdb_relation", prot, projection), con, true); + return rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, projection), con, true); } [[cpp11::register]] SEXP rapi_rel_aggregate(duckdb::rel_extptr_t rel, list groups, list aggregates) { diff --git a/src/reltoaltrep.cpp b/src/reltoaltrep.cpp index a19ae0e13..dca689284 100644 --- a/src/reltoaltrep.cpp +++ b/src/reltoaltrep.cpp @@ -340,7 +340,50 @@ static R_altrep_class_t LogicalTypeToAltrepType(const LogicalType &type) { } } -[[cpp11::register]] SEXP rapi_rel_to_altrep(duckdb::rel_extptr_t rel, duckdb::conn_eptr_t con, bool allow_materialization) { +[[cpp11::register]] SEXP rapi_rel_to_altrep(duckdb::rel_extptr_t rel, bool allow_materialization) { + D_ASSERT(rel && rel->rel); + auto drel = rel->rel; + auto ncols = drel->Columns().size(); + + auto relation_wrapper = make_shared_ptr(rel, allow_materialization); + + cpp11::writable::list data_frame; + data_frame.reserve(ncols); + + for (size_t col_idx = 0; col_idx < ncols; col_idx++) { + auto &column_type = drel->Columns()[col_idx].Type(); + cpp11::external_pointer ptr(new AltrepVectorWrapper(relation_wrapper, col_idx)); + R_SetExternalPtrTag(ptr, RStrings::get().duckdb_vector_sym); + + cpp11::sexp vector_sexp = R_new_altrep(LogicalTypeToAltrepType(column_type), ptr, rel); + duckdb_r_decorate(column_type, vector_sexp, false); + data_frame.push_back(vector_sexp); + } + + // convert to SEXP, with potential side effect of truncation and removal of attributes + (void)(SEXP)data_frame; + + // Names + vector names; + for (auto &col : drel->Columns()) { + names.push_back(col.Name()); + } + SET_NAMES(data_frame, StringsToSexp(names)); + + // Row names + cpp11::external_pointer ptr(new AltrepRownamesWrapper(relation_wrapper)); + R_SetExternalPtrTag(ptr, RStrings::get().duckdb_row_names_sym); + cpp11::sexp row_names_sexp = R_new_altrep(RelToAltrep::rownames_class, ptr, rel); + install_new_attrib(data_frame, R_RowNamesSymbol, row_names_sexp); + + // Class + data_frame.attr(R_ClassSymbol) = RStrings::get().dataframe_str; + + return data_frame; +} + + +SEXP rapi_rel_to_altrep2(duckdb::rel_extptr_t rel, duckdb::conn_eptr_t con, bool allow_materialization) { D_ASSERT(rel && rel->rel); auto drel = rel->rel; auto ncols = drel->Columns().size(); From dc1e31e8cf7f1203360d3cbb9cdc455e2f0de634 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Thu, 9 Jan 2025 17:19:32 +0100 Subject: [PATCH 15/69] Throw exception --- src/altrepdataframe_relation.cpp | 8 +++++++- src/include/altrepdataframe_relation.hpp | 13 ++++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/altrepdataframe_relation.cpp b/src/altrepdataframe_relation.cpp index 999748d40..d76efb0fc 100644 --- a/src/altrepdataframe_relation.cpp +++ b/src/altrepdataframe_relation.cpp @@ -38,7 +38,7 @@ Relation& AltrepDataFrameRelation::GetParent() { } } -Relation& AltrepDataFrameRelation::GetTableRelation() { +void AltrepDataFrameRelation::BuildTableRelation() { if (!table_function_relation) { named_parameter_map_t other_params; other_params["experimental"] = Value::BOOLEAN(false); @@ -47,6 +47,12 @@ Relation& AltrepDataFrameRelation::GetTableRelation() { table_function_relation = connection->conn->TableFunction("r_dataframe_scan", {Value::POINTER((uintptr_t)(SEXP)dataframe)}, other_params)->Alias(alias); } +} + +Relation& AltrepDataFrameRelation::GetTableRelation() { + if (!table_function_relation) { + throw RebuildRelationException(this); + } return *table_function_relation; } diff --git a/src/include/altrepdataframe_relation.hpp b/src/include/altrepdataframe_relation.hpp index b04bb02ea..d39ce40d7 100644 --- a/src/include/altrepdataframe_relation.hpp +++ b/src/include/altrepdataframe_relation.hpp @@ -21,10 +21,21 @@ class AltrepDataFrameRelation final : public Relation { string ToString(idx_t depth) override; bool IsReadOnly() override; + void BuildTableRelation(); + private: Relation& GetTableRelation(); Relation& GetParent(); }; -} +class RebuildRelationException : public std::exception { +public: + RebuildRelationException(AltrepDataFrameRelation* target_) : target(target_) { + } + +public: + AltrepDataFrameRelation* target; +}; + +} // namespace duckdb From 950f56825b3ee16c1509a8baf36934dfb0525ee1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Thu, 9 Jan 2025 17:22:32 +0100 Subject: [PATCH 16/69] Catching exception, but it occurs elsewhere --- src/reltoaltrep.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/reltoaltrep.cpp b/src/reltoaltrep.cpp index dca689284..a200b3fc8 100644 --- a/src/reltoaltrep.cpp +++ b/src/reltoaltrep.cpp @@ -127,7 +127,19 @@ MaterializedQueryResult *AltrepRelationWrapper::GetQueryResult() { duckdb_httplib::detail::scope_exit reset_max_expression_depth( [&]() { rel->context->GetContext()->config.max_expression_depth = old_depth; }); - res = rel->Execute(); + // We can't build the table relation on the fly because of a deadlock situation: + // The context is locked by Execute(), + // and a lock is attempted when creating a new Relation object. + while (true) { + try { + res = rel->Execute(); + } + catch (RebuildRelationException &e) { + e.target->BuildTableRelation(); + continue; + } + break; + } // FIXME: Use std::experimental::scope_exit if (rel->context->GetContext()->config.max_expression_depth != old_depth * 2) { From 43220c812aa402cab868a57e5262810d6a2973dc Mon Sep 17 00:00:00 2001 From: Antonov548 Date: Fri, 10 Jan 2025 11:12:35 +0100 Subject: [PATCH 17/69] relation rebuild --- src/relational.cpp | 70 +++++++++++++++++++++++++++++++++------------- 1 file changed, 50 insertions(+), 20 deletions(-) diff --git a/src/relational.cpp b/src/relational.cpp index c2810aa47..6a69881d1 100644 --- a/src/relational.cpp +++ b/src/relational.cpp @@ -174,21 +174,36 @@ SEXP rapi_rel_from_any_df(duckdb::conn_eptr_t con, SEXP df, bool allow_materiali } [[cpp11::register]] SEXP rapi_rel_filter2(data_frame df, duckdb::conn_eptr_t con, list exprs) { - duckdb::unique_ptr filter_expr; - if (exprs.size() == 0) { // nop - stop("expected filter expressions"); - } else if (exprs.size() == 1) { - filter_expr = ((expr_extptr_t)exprs[0])->Copy(); - } else { - vector> filters; - for (expr_extptr_t expr : exprs) { - filters.push_back(expr->Copy()); + auto build_filter_expr = [](const auto& _exprs) { + duckdb::unique_ptr filter_expr; + if (_exprs.size() == 0) { // nop + stop("expected filter expressions"); + } else if (_exprs.size() == 1) { + filter_expr = ((expr_extptr_t)_exprs[0])->Copy(); + } else { + vector> filters; + for (expr_extptr_t expr : _exprs) { + filters.push_back(expr->Copy()); + } + filter_expr = make_uniq(ExpressionType::CONJUNCTION_AND, std::move(filters)); } - filter_expr = make_uniq(ExpressionType::CONJUNCTION_AND, std::move(filters)); - } + + return filter_expr; + }; duckdb::rel_extptr_t rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); - auto filter = make_shared_ptr(rel->rel, std::move(filter_expr)); + shared_ptr filter; + + while (true) { + try { + filter = make_shared_ptr(rel->rel, build_filter_expr(exprs)); + } + catch (RebuildRelationException &e) { + e.target->BuildTableRelation(); + continue; + } + break; + } cpp11::writable::list prot = {rel}; @@ -220,18 +235,33 @@ SEXP rapi_rel_from_any_df(duckdb::conn_eptr_t con, SEXP df, bool allow_materiali if (exprs.size() == 0) { stop("expected projection expressions"); } - vector> projections; - vector aliases; + auto build_arguments = [](const auto& _exprs) { + vector aliases; + vector> projections; + for (expr_extptr_t expr : _exprs) { + auto dexpr = expr->Copy(); + aliases.push_back(dexpr->GetName()); + projections.push_back(std::move(dexpr)); + } - for (expr_extptr_t expr : exprs) { - auto dexpr = expr->Copy(); - aliases.push_back(dexpr->GetName()); - projections.push_back(std::move(dexpr)); - } + return std::make_pair(std::move(projections), std::move(aliases)); + }; duckdb::rel_extptr_t rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); - auto projection = make_shared_ptr(rel->rel, std::move(projections), std::move(aliases)); + shared_ptr projection; + + while (true) { + try { + auto&& [projections, aliases] = build_arguments(exprs); + projection = make_shared_ptr(rel->rel, std::move(projections), std::move(aliases)); + } + catch (RebuildRelationException &e) { + e.target->BuildTableRelation(); + continue; + } + break; + } cpp11::writable::list prot = {rel}; From bb46c8c6695dd1b22034a91cd73c1027015aec39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Fri, 10 Jan 2025 16:07:30 +0100 Subject: [PATCH 18/69] runtime_error --- src/include/altrepdataframe_relation.hpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/include/altrepdataframe_relation.hpp b/src/include/altrepdataframe_relation.hpp index d39ce40d7..eb272fc61 100644 --- a/src/include/altrepdataframe_relation.hpp +++ b/src/include/altrepdataframe_relation.hpp @@ -1,6 +1,7 @@ #include "duckdb/main/relation.hpp" #include "rapi.hpp" #include "reltoaltrep.hpp" +#include namespace duckdb { @@ -29,9 +30,9 @@ class AltrepDataFrameRelation final : public Relation { Relation& GetParent(); }; -class RebuildRelationException : public std::exception { +class RebuildRelationException : public std::runtime_error { public: - RebuildRelationException(AltrepDataFrameRelation* target_) : target(target_) { + RebuildRelationException(AltrepDataFrameRelation* target_) : std::runtime_error("RebuildRelationException"), target(target_) { } public: From e82f267321d9f6ae61a328e05fea76009046b0e6 Mon Sep 17 00:00:00 2001 From: Antonov548 Date: Tue, 14 Jan 2025 12:06:11 +0100 Subject: [PATCH 19/69] fix print method --- src/relational.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/relational.cpp b/src/relational.cpp index 6a69881d1..f41d0b4b1 100644 --- a/src/relational.cpp +++ b/src/relational.cpp @@ -513,10 +513,19 @@ static SEXP result_to_df(duckdb::unique_ptr res) { } [[cpp11::register]] std::string rapi_rel_tostring(duckdb::rel_extptr_t rel, std::string format) { - if (format == "tree") { - return rel->rel->ToString(0); - } else { - return rel->rel->ToString(); + while (true) { + try { + if (format == "tree") { + return rel->rel->ToString(0); + } else { + return rel->rel->ToString(); + } + } + catch (RebuildRelationException &e) { + e.target->BuildTableRelation(); + continue; + } + break; } } From 3257a09f11edba20a62b131e52f9be8db1f823b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Wed, 15 Jan 2025 10:47:28 +0100 Subject: [PATCH 20/69] Remove loop --- src/reltoaltrep.cpp | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/src/reltoaltrep.cpp b/src/reltoaltrep.cpp index a200b3fc8..dca689284 100644 --- a/src/reltoaltrep.cpp +++ b/src/reltoaltrep.cpp @@ -127,19 +127,7 @@ MaterializedQueryResult *AltrepRelationWrapper::GetQueryResult() { duckdb_httplib::detail::scope_exit reset_max_expression_depth( [&]() { rel->context->GetContext()->config.max_expression_depth = old_depth; }); - // We can't build the table relation on the fly because of a deadlock situation: - // The context is locked by Execute(), - // and a lock is attempted when creating a new Relation object. - while (true) { - try { - res = rel->Execute(); - } - catch (RebuildRelationException &e) { - e.target->BuildTableRelation(); - continue; - } - break; - } + res = rel->Execute(); // FIXME: Use std::experimental::scope_exit if (rel->context->GetContext()->config.max_expression_depth != old_depth * 2) { From 56e4f7a9adb8a1cb62bb30855466bb4732cd435c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Wed, 15 Jan 2025 10:57:37 +0100 Subject: [PATCH 21/69] Pass df --- src/include/reltoaltrep.hpp | 3 ++- src/reltoaltrep.cpp | 34 ++++++++++++++++++---------------- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/src/include/reltoaltrep.hpp b/src/include/reltoaltrep.hpp index 485016cd7..7037e15e2 100644 --- a/src/include/reltoaltrep.hpp +++ b/src/include/reltoaltrep.hpp @@ -5,7 +5,7 @@ namespace duckdb { struct AltrepRelationWrapper { - AltrepRelationWrapper(rel_extptr_t rel_, bool allow_materialization_); + AltrepRelationWrapper(rel_extptr_t rel_, bool allow_materialization_, SEXP df_); static AltrepRelationWrapper *Get(SEXP x); @@ -18,6 +18,7 @@ struct AltrepRelationWrapper { rel_extptr_t rel_eptr; duckdb::shared_ptr rel; duckdb::unique_ptr res; + cpp11::sexp df; }; } diff --git a/src/reltoaltrep.cpp b/src/reltoaltrep.cpp index dca689284..7135b17d6 100644 --- a/src/reltoaltrep.cpp +++ b/src/reltoaltrep.cpp @@ -92,8 +92,8 @@ AltrepRelationWrapper *AltrepRelationWrapper::Get(SEXP x) { return GetFromExternalPtr(x); } -AltrepRelationWrapper::AltrepRelationWrapper(rel_extptr_t rel_, bool allow_materialization_) - : allow_materialization(allow_materialization_), rel_eptr(rel_), rel(rel_->rel) { +AltrepRelationWrapper::AltrepRelationWrapper(rel_extptr_t rel_, bool allow_materialization_, SEXP df_) + : allow_materialization(allow_materialization_), rel_eptr(rel_), rel(rel_->rel), df(df_) { } bool AltrepRelationWrapper::HasQueryResult() const { @@ -345,10 +345,13 @@ static R_altrep_class_t LogicalTypeToAltrepType(const LogicalType &type) { auto drel = rel->rel; auto ncols = drel->Columns().size(); - auto relation_wrapper = make_shared_ptr(rel, allow_materialization); - cpp11::writable::list data_frame; - data_frame.reserve(ncols); + data_frame.resize(ncols); + + // convert to SEXP + (void)(SEXP)data_frame; + + auto relation_wrapper = make_shared_ptr(rel, allow_materialization, data_frame); for (size_t col_idx = 0; col_idx < ncols; col_idx++) { auto &column_type = drel->Columns()[col_idx].Type(); @@ -357,11 +360,9 @@ static R_altrep_class_t LogicalTypeToAltrepType(const LogicalType &type) { cpp11::sexp vector_sexp = R_new_altrep(LogicalTypeToAltrepType(column_type), ptr, rel); duckdb_r_decorate(column_type, vector_sexp, false); - data_frame.push_back(vector_sexp); - } - // convert to SEXP, with potential side effect of truncation and removal of attributes - (void)(SEXP)data_frame; + data_frame[col_idx] = vector_sexp; + } // Names vector names; @@ -388,10 +389,13 @@ SEXP rapi_rel_to_altrep2(duckdb::rel_extptr_t rel, duckdb::conn_eptr_t con, bool auto drel = rel->rel; auto ncols = drel->Columns().size(); - auto relation_wrapper = make_shared_ptr(rel, allow_materialization); - cpp11::writable::list data_frame; - data_frame.reserve(ncols); + data_frame.resize(ncols); + + auto relation_wrapper = make_shared_ptr(rel, allow_materialization, data_frame); + + // convert to SEXP + (void)(SEXP)data_frame; for (size_t col_idx = 0; col_idx < ncols; col_idx++) { auto &column_type = drel->Columns()[col_idx].Type(); @@ -400,11 +404,9 @@ SEXP rapi_rel_to_altrep2(duckdb::rel_extptr_t rel, duckdb::conn_eptr_t con, bool cpp11::sexp vector_sexp = R_new_altrep(LogicalTypeToAltrepType(column_type), ptr, rel); duckdb_r_decorate(column_type, vector_sexp, false); - data_frame.push_back(vector_sexp); - } - // convert to SEXP, with potential side effect of truncation and removal of attributes - (void)(SEXP)data_frame; + data_frame[col_idx] = vector_sexp; + } // Names vector names; From 55cfb5279e7b9c10faaa83e36adcf102da7373b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Wed, 15 Jan 2025 11:10:53 +0100 Subject: [PATCH 22/69] duckdb --- .../src/include/duckdb/main/connection.hpp | 6 +++--- .../src/include/duckdb/main/relation.hpp | 4 ++-- src/duckdb/src/main/connection.cpp | 18 +++++++++--------- src/duckdb/src/main/relation.cpp | 8 ++++---- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/duckdb/src/include/duckdb/main/connection.hpp b/src/duckdb/src/include/duckdb/main/connection.hpp index d0935ca8e..ebf7384ae 100644 --- a/src/duckdb/src/include/duckdb/main/connection.hpp +++ b/src/duckdb/src/include/duckdb/main/connection.hpp @@ -139,10 +139,10 @@ class Connection { DUCKDB_API shared_ptr View(const string &tname); DUCKDB_API shared_ptr View(const string &schema_name, const string &table_name); //! Returns a relation that calls a specified table function - DUCKDB_API shared_ptr TableFunction(const string &tname); + DUCKDB_API shared_ptr TableFunction(const string &tname, bool auto_init = true); DUCKDB_API shared_ptr TableFunction(const string &tname, const vector &values, - const named_parameter_map_t &named_parameters); - DUCKDB_API shared_ptr TableFunction(const string &tname, const vector &values); + const named_parameter_map_t &named_parameters, bool auto_init = true); + DUCKDB_API shared_ptr TableFunction(const string &tname, const vector &values, bool auto_init = true); //! Returns a relation that produces values DUCKDB_API shared_ptr Values(const vector> &values); DUCKDB_API shared_ptr Values(vector>> &&values); diff --git a/src/duckdb/src/include/duckdb/main/relation.hpp b/src/duckdb/src/include/duckdb/main/relation.hpp index 37b137aae..62ffeedb8 100644 --- a/src/duckdb/src/include/duckdb/main/relation.hpp +++ b/src/duckdb/src/include/duckdb/main/relation.hpp @@ -197,9 +197,9 @@ class Relation : public enable_shared_from_this { DUCKDB_API virtual void Delete(const string &condition = string()); //! Create a relation from calling a table in/out function on the input relation //! Create a relation from calling a table in/out function on the input relation - DUCKDB_API shared_ptr TableFunction(const std::string &fname, const vector &values); + DUCKDB_API shared_ptr TableFunction(const std::string &fname, const vector &values, bool auto_init = true); DUCKDB_API shared_ptr TableFunction(const std::string &fname, const vector &values, - const named_parameter_map_t &named_parameters); + const named_parameter_map_t &named_parameters, bool auto_init = true); public: //! Whether or not the relation inherits column bindings from its child or not, only relevant for binding diff --git a/src/duckdb/src/main/connection.cpp b/src/duckdb/src/main/connection.cpp index 10dddcd4f..99cc06964 100644 --- a/src/duckdb/src/main/connection.cpp +++ b/src/duckdb/src/main/connection.cpp @@ -245,19 +245,19 @@ shared_ptr Connection::View(const string &schema_name, const string &t return make_shared_ptr(context, schema_name, table_name); } -shared_ptr Connection::TableFunction(const string &fname) { - vector values; - named_parameter_map_t named_parameters; - return TableFunction(fname, values, named_parameters); +shared_ptr Connection::TableFunction(const string &fname, const vector &values, + const named_parameter_map_t &named_parameters, bool auto_init) { + return make_shared_ptr(context, fname, values, named_parameters, nullptr, auto_init); } -shared_ptr Connection::TableFunction(const string &fname, const vector &values, - const named_parameter_map_t &named_parameters) { - return make_shared_ptr(context, fname, values, named_parameters); +shared_ptr Connection::TableFunction(const string &fname, const vector &values, bool auto_init) { + return make_shared_ptr(context, fname, values, nullptr, auto_init); } -shared_ptr Connection::TableFunction(const string &fname, const vector &values) { - return make_shared_ptr(context, fname, values); +shared_ptr Connection::TableFunction(const string &fname, bool auto_init) { + vector values; + named_parameter_map_t named_parameters; + return TableFunction(fname, values, named_parameters, auto_init); } shared_ptr Connection::Values(const vector> &values) { diff --git a/src/duckdb/src/main/relation.cpp b/src/duckdb/src/main/relation.cpp index 9154822f9..3e65ce993 100644 --- a/src/duckdb/src/main/relation.cpp +++ b/src/duckdb/src/main/relation.cpp @@ -369,13 +369,13 @@ void Relation::Delete(const string &condition) { } shared_ptr Relation::TableFunction(const std::string &fname, const vector &values, - const named_parameter_map_t &named_parameters) { + const named_parameter_map_t &named_parameters, bool auto_init) { return make_shared_ptr(context->GetContext(), fname, values, named_parameters, - shared_from_this()); + shared_from_this(), auto_init); } -shared_ptr Relation::TableFunction(const std::string &fname, const vector &values) { - return make_shared_ptr(context->GetContext(), fname, values, shared_from_this()); +shared_ptr Relation::TableFunction(const std::string &fname, const vector &values, bool auto_init) { + return make_shared_ptr(context->GetContext(), fname, values, shared_from_this(), auto_init); } string Relation::ToString() { From 3081a21db3641d21c7eafd5a977ea5b656765cc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Wed, 15 Jan 2025 11:11:03 +0100 Subject: [PATCH 23/69] No auto_init --- src/altrepdataframe_relation.cpp | 2 +- src/relational.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/altrepdataframe_relation.cpp b/src/altrepdataframe_relation.cpp index d76efb0fc..b83770a31 100644 --- a/src/altrepdataframe_relation.cpp +++ b/src/altrepdataframe_relation.cpp @@ -45,7 +45,7 @@ void AltrepDataFrameRelation::BuildTableRelation() { auto alias = StringUtil::Format("dataframe_%d_%d", (uintptr_t)(SEXP)dataframe, (int32_t)(NumericLimits::Maximum() * unif_rand())); - table_function_relation = connection->conn->TableFunction("r_dataframe_scan", {Value::POINTER((uintptr_t)(SEXP)dataframe)}, other_params)->Alias(alias); + table_function_relation = connection->conn->TableFunction("r_dataframe_scan", {Value::POINTER((uintptr_t)(SEXP)dataframe)}, other_params, false)->Alias(alias); } } diff --git a/src/relational.cpp b/src/relational.cpp index f41d0b4b1..bcbc0a41e 100644 --- a/src/relational.cpp +++ b/src/relational.cpp @@ -134,7 +134,7 @@ using namespace cpp11; auto alias = StringUtil::Format("dataframe_%d_%d", (uintptr_t)(SEXP)df, (int32_t)(NumericLimits::Maximum() * unif_rand())); auto rel = - con->conn->TableFunction("r_dataframe_scan", {Value::POINTER((uintptr_t)(SEXP)df)}, other_params)->Alias(alias); + con->conn->TableFunction("r_dataframe_scan", {Value::POINTER((uintptr_t)(SEXP)df)}, other_params, false)->Alias(alias); cpp11::writable::list prot = {df}; From 7c1799d29fed081cab3b40ac585db5562f2cc0ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Wed, 15 Jan 2025 11:14:21 +0100 Subject: [PATCH 24/69] Can now remove loops for operators, but not for printing --- src/relational.cpp | 24 +++--------------------- 1 file changed, 3 insertions(+), 21 deletions(-) diff --git a/src/relational.cpp b/src/relational.cpp index bcbc0a41e..c7b787db8 100644 --- a/src/relational.cpp +++ b/src/relational.cpp @@ -194,16 +194,7 @@ SEXP rapi_rel_from_any_df(duckdb::conn_eptr_t con, SEXP df, bool allow_materiali shared_ptr filter; - while (true) { - try { - filter = make_shared_ptr(rel->rel, build_filter_expr(exprs)); - } - catch (RebuildRelationException &e) { - e.target->BuildTableRelation(); - continue; - } - break; - } + filter = make_shared_ptr(rel->rel, build_filter_expr(exprs)); cpp11::writable::list prot = {rel}; @@ -251,17 +242,8 @@ SEXP rapi_rel_from_any_df(duckdb::conn_eptr_t con, SEXP df, bool allow_materiali shared_ptr projection; - while (true) { - try { - auto&& [projections, aliases] = build_arguments(exprs); - projection = make_shared_ptr(rel->rel, std::move(projections), std::move(aliases)); - } - catch (RebuildRelationException &e) { - e.target->BuildTableRelation(); - continue; - } - break; - } + auto&& [projections, aliases] = build_arguments(exprs); + projection = make_shared_ptr(rel->rel, std::move(projections), std::move(aliases)); cpp11::writable::list prot = {rel}; From 4b33d77f80cd8c122874fb084ebb98a3ba6cbbbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Wed, 15 Jan 2025 11:16:18 +0100 Subject: [PATCH 25/69] Don't throw --- src/altrepdataframe_relation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/altrepdataframe_relation.cpp b/src/altrepdataframe_relation.cpp index b83770a31..7009c44fb 100644 --- a/src/altrepdataframe_relation.cpp +++ b/src/altrepdataframe_relation.cpp @@ -51,7 +51,7 @@ void AltrepDataFrameRelation::BuildTableRelation() { Relation& AltrepDataFrameRelation::GetTableRelation() { if (!table_function_relation) { - throw RebuildRelationException(this); + BuildTableRelation(); } return *table_function_relation; From 918afaad203fbbb1dbba73e4b1854b48c2f286f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Wed, 15 Jan 2025 11:18:01 +0100 Subject: [PATCH 26/69] Can now remove loops --- src/relational.cpp | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/src/relational.cpp b/src/relational.cpp index c7b787db8..ae54e3708 100644 --- a/src/relational.cpp +++ b/src/relational.cpp @@ -495,19 +495,10 @@ static SEXP result_to_df(duckdb::unique_ptr res) { } [[cpp11::register]] std::string rapi_rel_tostring(duckdb::rel_extptr_t rel, std::string format) { - while (true) { - try { - if (format == "tree") { - return rel->rel->ToString(0); - } else { - return rel->rel->ToString(); - } - } - catch (RebuildRelationException &e) { - e.target->BuildTableRelation(); - continue; - } - break; + if (format == "tree") { + return rel->rel->ToString(0); + } else { + return rel->rel->ToString(); } } From 01d4292e4fba102b8440e7472532dd485a97716d Mon Sep 17 00:00:00 2001 From: Antonov548 Date: Thu, 16 Jan 2025 11:18:52 +0100 Subject: [PATCH 27/69] move to `relational2.cpp` --- src/relational.cpp | 56 --------------------------------- src/relational2.cpp | 76 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 56 deletions(-) create mode 100644 src/relational2.cpp diff --git a/src/relational.cpp b/src/relational.cpp index ae54e3708..99f6cc72f 100644 --- a/src/relational.cpp +++ b/src/relational.cpp @@ -173,34 +173,6 @@ SEXP rapi_rel_from_any_df(duckdb::conn_eptr_t con, SEXP df, bool allow_materiali return make_external_prot("duckdb_relation", prot, res); } -[[cpp11::register]] SEXP rapi_rel_filter2(data_frame df, duckdb::conn_eptr_t con, list exprs) { - auto build_filter_expr = [](const auto& _exprs) { - duckdb::unique_ptr filter_expr; - if (_exprs.size() == 0) { // nop - stop("expected filter expressions"); - } else if (_exprs.size() == 1) { - filter_expr = ((expr_extptr_t)_exprs[0])->Copy(); - } else { - vector> filters; - for (expr_extptr_t expr : _exprs) { - filters.push_back(expr->Copy()); - } - filter_expr = make_uniq(ExpressionType::CONJUNCTION_AND, std::move(filters)); - } - - return filter_expr; - }; - duckdb::rel_extptr_t rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); - - shared_ptr filter; - - filter = make_shared_ptr(rel->rel, build_filter_expr(exprs)); - - cpp11::writable::list prot = {rel}; - - return rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, filter), con, true); -} - [[cpp11::register]] SEXP rapi_rel_project(duckdb::rel_extptr_t rel, list exprs) { if (exprs.size() == 0) { warning("rel_project without projection expressions has no effect"); @@ -222,34 +194,6 @@ SEXP rapi_rel_from_any_df(duckdb::conn_eptr_t con, SEXP df, bool allow_materiali return make_external_prot("duckdb_relation", prot, res); } -[[cpp11::register]] SEXP rapi_rel_project2(data_frame df, duckdb::conn_eptr_t con, list exprs) { - if (exprs.size() == 0) { - stop("expected projection expressions"); - } - auto build_arguments = [](const auto& _exprs) { - vector aliases; - vector> projections; - for (expr_extptr_t expr : _exprs) { - auto dexpr = expr->Copy(); - aliases.push_back(dexpr->GetName()); - projections.push_back(std::move(dexpr)); - } - - return std::make_pair(std::move(projections), std::move(aliases)); - }; - - duckdb::rel_extptr_t rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); - - shared_ptr projection; - - auto&& [projections, aliases] = build_arguments(exprs); - projection = make_shared_ptr(rel->rel, std::move(projections), std::move(aliases)); - - cpp11::writable::list prot = {rel}; - - return rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, projection), con, true); -} - [[cpp11::register]] SEXP rapi_rel_aggregate(duckdb::rel_extptr_t rel, list groups, list aggregates) { vector> res_groups, res_aggregates; diff --git a/src/relational2.cpp b/src/relational2.cpp new file mode 100644 index 000000000..dcd7543d9 --- /dev/null +++ b/src/relational2.cpp @@ -0,0 +1,76 @@ +#include "rapi.hpp" +#include "signal.hpp" +#include "typesr.hpp" +#include "reltoaltrep.hpp" +#include "altrepdataframe_relation.hpp" + +#include "R_ext/Random.h" + +#include "duckdb/parser/expression/columnref_expression.hpp" +#include "duckdb/parser/expression/constant_expression.hpp" +#include "duckdb/parser/expression/comparison_expression.hpp" +#include "duckdb/parser/expression/function_expression.hpp" +#include "duckdb/parser/expression/comparison_expression.hpp" +#include "duckdb/parser/expression/conjunction_expression.hpp" +#include "duckdb/parser/expression/window_expression.hpp" + +#include "duckdb/main/relation/filter_relation.hpp" +#include "duckdb/main/relation/projection_relation.hpp" +#include "duckdb/main/relation/aggregate_relation.hpp" +#include "duckdb/main/relation/order_relation.hpp" +#include "duckdb/main/relation/join_relation.hpp" +#include "duckdb/main/relation/cross_product_relation.hpp" +#include "duckdb/main/relation/setop_relation.hpp" +#include "duckdb/main/relation/limit_relation.hpp" +#include "duckdb/main/relation/distinct_relation.hpp" + +using namespace duckdb; +using namespace cpp11; + +// DuckDB Expressions + +[[cpp11::register]] SEXP rapi_rel_project2(data_frame df, duckdb::conn_eptr_t con, list exprs) { + if (exprs.size() == 0) { + stop("expected projection expressions"); + } + vector> projections; + vector aliases; + + for (expr_extptr_t expr : exprs) { + auto dexpr = expr->Copy(); + aliases.push_back(dexpr->GetName()); + projections.push_back(std::move(dexpr)); + } + + + duckdb::rel_extptr_t rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); + + auto projection = make_shared_ptr(rel->rel, std::move(projections), std::move(aliases)); + + cpp11::writable::list prot = {rel}; + + return rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, projection), con, true); +} + +[[cpp11::register]] SEXP rapi_rel_filter2(data_frame df, duckdb::conn_eptr_t con, list exprs) { + duckdb::unique_ptr filter_expr; + if (exprs.size() == 0) { // nop + warning("rel_filter without filter expressions has no effect"); + return df; + } else if (exprs.size() == 1) { + filter_expr = ((expr_extptr_t)exprs[0])->Copy(); + } else { + vector> filters; + for (expr_extptr_t expr : exprs) { + filters.push_back(expr->Copy()); + } + filter_expr = make_uniq(ExpressionType::CONJUNCTION_AND, std::move(filters)); + } + duckdb::rel_extptr_t rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); + + auto filter = make_shared_ptr(rel->rel, std::move(filter_expr)); + + cpp11::writable::list prot = {rel}; + + return rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, filter), con, true); +} From 194888ff6e20e5d0f6eb00974987794de3f75e5e Mon Sep 17 00:00:00 2001 From: Antonov548 Date: Thu, 16 Jan 2025 11:18:59 +0100 Subject: [PATCH 28/69] update Makevars --- src/Makevars | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makevars b/src/Makevars index 939f119ea..802314733 100644 --- a/src/Makevars +++ b/src/Makevars @@ -16,4 +16,4 @@ include Makevars.duckdb CXX_STD = CXX17 PKG_CPPFLAGS = -Iinclude -I../inst/include -DDUCKDB_DISABLE_PRINT -DDUCKDB_R_BUILD -DBROTLI_ENCODER_CLEANUP_ON_OOM -Iduckdb/src/include -Iduckdb/third_party/concurrentqueue -Iduckdb/third_party/fast_float -Iduckdb/third_party/fastpforlib -Iduckdb/third_party/fmt/include -Iduckdb/third_party/fsst -Iduckdb/third_party/httplib -Iduckdb/third_party/hyperloglog -Iduckdb/third_party/jaro_winkler -Iduckdb/third_party/jaro_winkler/details -Iduckdb/third_party/libpg_query -Iduckdb/third_party/libpg_query/include -Iduckdb/third_party/lz4 -Iduckdb/third_party/brotli/include -Iduckdb/third_party/brotli/common -Iduckdb/third_party/brotli/dec -Iduckdb/third_party/brotli/enc -Iduckdb/third_party/mbedtls -Iduckdb/third_party/mbedtls/include -Iduckdb/third_party/mbedtls/library -Iduckdb/third_party/miniz -Iduckdb/third_party/pcg -Iduckdb/third_party/re2 -Iduckdb/third_party/skiplist -Iduckdb/third_party/tdigest -Iduckdb/third_party/utf8proc -Iduckdb/third_party/utf8proc/include -Iduckdb/third_party/yyjson/include -Iduckdb/third_party/zstd/include -Iduckdb/extension/parquet/include -Iduckdb/third_party/parquet -Iduckdb/third_party/thrift -Iduckdb/third_party/lz4 -Iduckdb/third_party/brotli/include -Iduckdb/third_party/brotli/common -Iduckdb/third_party/brotli/dec -Iduckdb/third_party/brotli/enc -Iduckdb/third_party/snappy -Iduckdb/third_party/mbedtls -Iduckdb/third_party/mbedtls/include -Iduckdb/third_party/zstd/include -Iduckdb/extension/core_functions/include -I../inst/include -Iduckdb -DDUCKDB_EXTENSION_PARQUET_LINKED -DDUCKDB_BUILD_LIBRARY -DDUCKDB_EXTENSION_CORE_FUNCTIONS_LINKED -DDUCKDB_BUILD_LIBRARY -OBJECTS=rfuns.o database.o connection.o statement.o register.o relational.o scan.o signal.o transform.o utils.o reltoaltrep.o altrepdataframe_relation.o types.o cpp11.o $(SOURCES) +OBJECTS=rfuns.o database.o connection.o statement.o register.o relational.o relational2.o scan.o signal.o transform.o utils.o reltoaltrep.o altrepdataframe_relation.o types.o cpp11.o $(SOURCES) From f08a38d92d562f9a0226a95f3126031f9d0dbcff Mon Sep 17 00:00:00 2001 From: Antonov548 Date: Thu, 16 Jan 2025 11:51:01 +0100 Subject: [PATCH 29/69] add aggregate2/order2/join2 --- src/relational2.cpp | 116 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 114 insertions(+), 2 deletions(-) diff --git a/src/relational2.cpp b/src/relational2.cpp index dcd7543d9..a9059bb1c 100644 --- a/src/relational2.cpp +++ b/src/relational2.cpp @@ -49,7 +49,7 @@ using namespace cpp11; cpp11::writable::list prot = {rel}; - return rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, projection), con, true); + return rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, std::move(projection)), con, true); } [[cpp11::register]] SEXP rapi_rel_filter2(data_frame df, duckdb::conn_eptr_t con, list exprs) { @@ -72,5 +72,117 @@ using namespace cpp11; cpp11::writable::list prot = {rel}; - return rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, filter), con, true); + return rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, std::move(filter)), con, true); +} + +[[cpp11::register]] SEXP rapi_rel_aggregate2(data_frame df, duckdb::conn_eptr_t con, list groups, list aggregates) { + vector> res_groups, res_aggregates; + + // TODO deal with empty groups + vector aliases; + + for (expr_extptr_t expr : groups) { + res_groups.push_back(expr->Copy()); + res_aggregates.push_back(expr->Copy()); + } + + int aggr_idx = 0; // has to be int for - reasons + auto aggr_names = aggregates.names(); + + for (expr_extptr_t expr_p : aggregates) { + auto expr = expr_p->Copy(); + if (aggr_names.size() > aggr_idx) { + expr->alias = aggr_names[aggr_idx]; + } + res_aggregates.push_back(std::move(expr)); + aggr_idx++; + } + duckdb::rel_extptr_t rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); + + auto aggregate = make_shared_ptr(rel->rel, std::move(res_aggregates), std::move(res_groups)); + + cpp11::writable::list prot = {rel}; + + return rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, std::move(aggregate)), con, true); +} + +[[cpp11::register]] SEXP rapi_rel_order2(data_frame df, duckdb::conn_eptr_t con, list orders, r_vector ascending) { + vector res_orders; + + OrderType order_type; + size_t i = 0; + + for (expr_extptr_t expr : orders) { + order_type = ascending[i] ? OrderType::ASCENDING : OrderType::DESCENDING; + i++; + res_orders.emplace_back(order_type, OrderByNullType::NULLS_LAST, expr->Copy()); + } + + duckdb::rel_extptr_t rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); + + auto order = make_shared_ptr(rel->rel, std::move(res_orders)); + + cpp11::writable::list prot = {rel}; + + return rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, std::move(order)), con, true); +} + +[[cpp11::register]] SEXP rapi_rel_join2(data_frame left, data_frame right, duckdb::conn_eptr_t con, list conds, + std::string join, std::string join_ref_type) { + auto join_type = JoinType::INNER; + auto ref_type = JoinRefType::REGULAR; + unique_ptr cond; + + if (join_ref_type == "regular") { + ref_type = JoinRefType::REGULAR; + } else if (join_ref_type == "cross") { + ref_type = JoinRefType::CROSS; + } else if (join_ref_type == "positional") { + ref_type = JoinRefType::POSITIONAL; + } else if (join_ref_type == "asof") { + ref_type = JoinRefType::ASOF; + } + + duckdb::rel_extptr_t rel_left = cpp11::as_cpp>(rapi_rel_from_any_df(con, left, true)); + duckdb::rel_extptr_t rel_right = cpp11::as_cpp>(rapi_rel_from_any_df(con, right, true)); + + cpp11::writable::list prot = {rel_left, rel_right}; + + if (join == "left") { + join_type = JoinType::LEFT; + } else if (join == "right") { + join_type = JoinType::RIGHT; + } else if (join == "outer") { + join_type = JoinType::OUTER; + } else if (join == "semi") { + join_type = JoinType::SEMI; + } else if (join == "anti") { + join_type = JoinType::ANTI; + } else if (join == "cross" || ref_type == JoinRefType::POSITIONAL) { + if (ref_type != JoinRefType::POSITIONAL && ref_type != JoinRefType::CROSS) { + // users can only supply positional cross join, or cross join. + warning("Using `rel_join(join_ref_type = \"cross\")`"); + ref_type = JoinRefType::CROSS; + } + auto res = make_shared_ptr(rel_left->rel, rel_right->rel, ref_type); + auto df = rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, std::move(res)), con, true); + // if the user described filters, apply them on top of the cross product relation + if (conds.size() > 0) { + return rapi_rel_filter2(df, con, conds); + } + return df; + } + + if (conds.size() == 1) { + cond = ((expr_extptr_t)conds[0])->Copy(); + } else { + vector> cond_args; + for (expr_extptr_t expr : conds) { + cond_args.push_back(expr->Copy()); + } + cond = make_uniq(ExpressionType::CONJUNCTION_AND, std::move(cond_args)); + } + + auto res = make_shared_ptr(rel_left->rel, rel_right->rel, std::move(cond), join_type, ref_type); + return rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, std::move(res)), con, true); } From b06fbbbca4cbf50a53df7bf2d71d95db7f8bf087 Mon Sep 17 00:00:00 2001 From: Antonov548 Date: Thu, 16 Jan 2025 11:57:03 +0100 Subject: [PATCH 30/69] update R interface --- R/cpp11.R | 28 ++++++++++++++++++-------- R/relational.R | 37 +++++++++++++++++++++++++++++++++++ R/rethrow-gen.R | 20 +++++++++++++++++++ src/cpp11.cpp | 52 ++++++++++++++++++++++++++++++++++++------------- 4 files changed, 115 insertions(+), 22 deletions(-) diff --git a/R/cpp11.R b/R/cpp11.R index 9e7c9f740..297f4888a 100644 --- a/R/cpp11.R +++ b/R/cpp11.R @@ -80,18 +80,10 @@ rapi_rel_filter <- function(rel, exprs) { .Call(`_duckdb_rapi_rel_filter`, rel, exprs) } -rapi_rel_filter2 <- function(df, con, exprs) { - .Call(`_duckdb_rapi_rel_filter2`, df, con, exprs) -} - rapi_rel_project <- function(rel, exprs) { .Call(`_duckdb_rapi_rel_project`, rel, exprs) } -rapi_rel_project2 <- function(df, con, exprs) { - .Call(`_duckdb_rapi_rel_project2`, df, con, exprs) -} - rapi_rel_aggregate <- function(rel, groups, aggregates) { .Call(`_duckdb_rapi_rel_aggregate`, rel, groups, aggregates) } @@ -196,6 +188,26 @@ rapi_rel_insert <- function(rel, schema_name, table_name) { invisible(.Call(`_duckdb_rapi_rel_insert`, rel, schema_name, table_name)) } +rapi_rel_project2 <- function(df, con, exprs) { + .Call(`_duckdb_rapi_rel_project2`, df, con, exprs) +} + +rapi_rel_filter2 <- function(df, con, exprs) { + .Call(`_duckdb_rapi_rel_filter2`, df, con, exprs) +} + +rapi_rel_aggregate2 <- function(df, con, groups, aggregates) { + .Call(`_duckdb_rapi_rel_aggregate2`, df, con, groups, aggregates) +} + +rapi_rel_order2 <- function(df, con, orders, ascending) { + .Call(`_duckdb_rapi_rel_order2`, df, con, orders, ascending) +} + +rapi_rel_join2 <- function(left, right, con, conds, join, join_ref_type) { + .Call(`_duckdb_rapi_rel_join2`, left, right, con, conds, join, join_ref_type) +} + rapi_rel_to_altrep <- function(rel, allow_materialization) { .Call(`_duckdb_rapi_rel_to_altrep`, rel, allow_materialization) } diff --git a/R/relational.R b/R/relational.R index 5fa1a61c4..1115e8b49 100644 --- a/R/relational.R +++ b/R/relational.R @@ -189,6 +189,21 @@ rel_aggregate <- function(rel, groups, aggregates) { rethrow_rapi_rel_aggregate(rel, groups, aggregates) } +#' Lazily aggregate a DuckDB relation object +#' @param rel the DuckDB relation object +#' @param groups a list of DuckDB expressions to group by +#' @param aggregates a (optionally named) list of DuckDB expressions with aggregates to compute +#' @return the now aggregated `duckdb_relation` object +#' @noRd +#' @examples +#' con <- DBI::dbConnect(duckdb()) +#' rel <- rel_from_df(con, mtcars) +#' aggrs <- list(avg_hp = expr_function("avg", list(expr_reference("hp")))) +#' rel2 <- rel_aggregate(rel, list(expr_reference("cyl")), aggrs) +rel_aggregate2 <- function(rel, con, groups, aggregates) { + rethrow_rapi_rel_aggregate2(rel, con@conn_ref, groups, aggregates) +} + #' Lazily reorder a DuckDB relation object #' @param rel the DuckDB relation object #' @param orders a list of DuckDB expressions to order by @@ -211,6 +226,28 @@ rel_order <- function(rel, orders, ascending = NULL) { return(rethrow_rapi_rel_order(rel, orders, ascending)) } +#' Lazily reorder a DuckDB relation object +#' @param rel the DuckDB relation object +#' @param orders a list of DuckDB expressions to order by +#' @param ascending a vector of boolean values describing sort order of expressions. True for ascending. +#' @return the now aggregated `duckdb_relation` object +#' @noRd +#' @examples +#' con <- DBI::dbConnect(duckdb()) +#' rel <- rel_from_df(con, mtcars) +#' rel2 <- rel_order(rel, list(expr_reference("hp"))) +rel_order2 <- function(rel, con, orders, ascending = NULL) { + if (is.null(ascending)) { + ascending <- rep(TRUE, length(orders)) + } + + if (length(orders) != length(ascending)) { + stop("length of ascending must equal length of orders") + } + + return(rethrow_rapi_rel_order2(rel, con@conn_ref, orders, ascending)) +} + #' Get an external pointer pointing to NULL #' @return an external pointer pointing to null_ptr. #' @noRd diff --git a/R/rethrow-gen.R b/R/rethrow-gen.R index 36d1a36aa..34eaaa3fc 100644 --- a/R/rethrow-gen.R +++ b/R/rethrow-gen.R @@ -216,6 +216,15 @@ rethrow_rapi_rel_aggregate <- function(rel, groups, aggregates, call = parent.fr ) } +rethrow_rapi_rel_aggregate2 <- function(rel, con, groups, aggregates, call = parent.frame(2)) { + rlang::try_fetch( + rapi_rel_aggregate2(rel, con, groups, aggregates), + error = function(e) { + rethrow_error_from_rapi(e, call) + } + ) +} + rethrow_rapi_rel_order <- function(rel, orders, ascending, call = parent.frame(2)) { rlang::try_fetch( rapi_rel_order(rel, orders, ascending), @@ -225,6 +234,15 @@ rethrow_rapi_rel_order <- function(rel, orders, ascending, call = parent.frame(2 ) } +rethrow_rapi_rel_order2 <- function(rel, con, orders, ascending, call = parent.frame(2)) { + rlang::try_fetch( + rapi_rel_order2(rel, con, orders, ascending), + error = function(e) { + rethrow_error_from_rapi(e, call) + } + ) +} + rethrow_rapi_expr_window <- function(window_function, partitions, order_bys, window_boundary_start, window_boundary_end, start_expr, end_expr, offset_expr, default_expr, call = parent.frame(2)) { rlang::try_fetch( rapi_expr_window(window_function, partitions, order_bys, window_boundary_start, window_boundary_end, start_expr, end_expr, offset_expr, default_expr), @@ -601,7 +619,9 @@ rethrow_restore <- function() { rethrow_rapi_rel_project <<- rapi_rel_project rethrow_rapi_rel_project2 <<- rapi_rel_project2 rethrow_rapi_rel_aggregate <<- rapi_rel_aggregate + rethrow_rapi_rel_aggregate2 <<- rapi_rel_aggregate2 rethrow_rapi_rel_order <<- rapi_rel_order + rethrow_rapi_rel_order2 <<- rapi_rel_order2 rethrow_rapi_expr_window <<- rapi_expr_window rethrow_rapi_rel_join <<- rapi_rel_join rethrow_rapi_rel_union_all <<- rapi_rel_union_all diff --git a/src/cpp11.cpp b/src/cpp11.cpp index 6e1e93a10..2bbcc318c 100644 --- a/src/cpp11.cpp +++ b/src/cpp11.cpp @@ -154,13 +154,6 @@ extern "C" SEXP _duckdb_rapi_rel_filter(SEXP rel, SEXP exprs) { END_CPP11 } // relational.cpp -SEXP rapi_rel_filter2(data_frame df, duckdb::conn_eptr_t con, list exprs); -extern "C" SEXP _duckdb_rapi_rel_filter2(SEXP df, SEXP con, SEXP exprs) { - BEGIN_CPP11 - return cpp11::as_sexp(rapi_rel_filter2(cpp11::as_cpp>(df), cpp11::as_cpp>(con), cpp11::as_cpp>(exprs))); - END_CPP11 -} -// relational.cpp SEXP rapi_rel_project(duckdb::rel_extptr_t rel, list exprs); extern "C" SEXP _duckdb_rapi_rel_project(SEXP rel, SEXP exprs) { BEGIN_CPP11 @@ -168,13 +161,6 @@ extern "C" SEXP _duckdb_rapi_rel_project(SEXP rel, SEXP exprs) { END_CPP11 } // relational.cpp -SEXP rapi_rel_project2(data_frame df, duckdb::conn_eptr_t con, list exprs); -extern "C" SEXP _duckdb_rapi_rel_project2(SEXP df, SEXP con, SEXP exprs) { - BEGIN_CPP11 - return cpp11::as_sexp(rapi_rel_project2(cpp11::as_cpp>(df), cpp11::as_cpp>(con), cpp11::as_cpp>(exprs))); - END_CPP11 -} -// relational.cpp SEXP rapi_rel_aggregate(duckdb::rel_extptr_t rel, list groups, list aggregates); extern "C" SEXP _duckdb_rapi_rel_aggregate(SEXP rel, SEXP groups, SEXP aggregates) { BEGIN_CPP11 @@ -360,6 +346,41 @@ extern "C" SEXP _duckdb_rapi_rel_insert(SEXP rel, SEXP schema_name, SEXP table_n return R_NilValue; END_CPP11 } +// relational2.cpp +SEXP rapi_rel_project2(data_frame df, duckdb::conn_eptr_t con, list exprs); +extern "C" SEXP _duckdb_rapi_rel_project2(SEXP df, SEXP con, SEXP exprs) { + BEGIN_CPP11 + return cpp11::as_sexp(rapi_rel_project2(cpp11::as_cpp>(df), cpp11::as_cpp>(con), cpp11::as_cpp>(exprs))); + END_CPP11 +} +// relational2.cpp +SEXP rapi_rel_filter2(data_frame df, duckdb::conn_eptr_t con, list exprs); +extern "C" SEXP _duckdb_rapi_rel_filter2(SEXP df, SEXP con, SEXP exprs) { + BEGIN_CPP11 + return cpp11::as_sexp(rapi_rel_filter2(cpp11::as_cpp>(df), cpp11::as_cpp>(con), cpp11::as_cpp>(exprs))); + END_CPP11 +} +// relational2.cpp +SEXP rapi_rel_aggregate2(data_frame df, duckdb::conn_eptr_t con, list groups, list aggregates); +extern "C" SEXP _duckdb_rapi_rel_aggregate2(SEXP df, SEXP con, SEXP groups, SEXP aggregates) { + BEGIN_CPP11 + return cpp11::as_sexp(rapi_rel_aggregate2(cpp11::as_cpp>(df), cpp11::as_cpp>(con), cpp11::as_cpp>(groups), cpp11::as_cpp>(aggregates))); + END_CPP11 +} +// relational2.cpp +SEXP rapi_rel_order2(data_frame df, duckdb::conn_eptr_t con, list orders, r_vector ascending); +extern "C" SEXP _duckdb_rapi_rel_order2(SEXP df, SEXP con, SEXP orders, SEXP ascending) { + BEGIN_CPP11 + return cpp11::as_sexp(rapi_rel_order2(cpp11::as_cpp>(df), cpp11::as_cpp>(con), cpp11::as_cpp>(orders), cpp11::as_cpp>>(ascending))); + END_CPP11 +} +// relational2.cpp +SEXP rapi_rel_join2(data_frame left, data_frame right, duckdb::conn_eptr_t con, list conds, std::string join, std::string join_ref_type); +extern "C" SEXP _duckdb_rapi_rel_join2(SEXP left, SEXP right, SEXP con, SEXP conds, SEXP join, SEXP join_ref_type) { + BEGIN_CPP11 + return cpp11::as_sexp(rapi_rel_join2(cpp11::as_cpp>(left), cpp11::as_cpp>(right), cpp11::as_cpp>(con), cpp11::as_cpp>(conds), cpp11::as_cpp>(join), cpp11::as_cpp>(join_ref_type))); + END_CPP11 +} // reltoaltrep.cpp SEXP rapi_rel_to_altrep(duckdb::rel_extptr_t rel, bool allow_materialization); extern "C" SEXP _duckdb_rapi_rel_to_altrep(SEXP rel, SEXP allow_materialization) { @@ -498,6 +519,7 @@ static const R_CallMethodDef CallEntries[] = { {"_duckdb_rapi_register_arrow", (DL_FUNC) &_duckdb_rapi_register_arrow, 4}, {"_duckdb_rapi_register_df", (DL_FUNC) &_duckdb_rapi_register_df, 6}, {"_duckdb_rapi_rel_aggregate", (DL_FUNC) &_duckdb_rapi_rel_aggregate, 3}, + {"_duckdb_rapi_rel_aggregate2", (DL_FUNC) &_duckdb_rapi_rel_aggregate2, 4}, {"_duckdb_rapi_rel_alias", (DL_FUNC) &_duckdb_rapi_rel_alias, 1}, {"_duckdb_rapi_rel_distinct", (DL_FUNC) &_duckdb_rapi_rel_distinct, 1}, {"_duckdb_rapi_rel_explain", (DL_FUNC) &_duckdb_rapi_rel_explain, 3}, @@ -510,9 +532,11 @@ static const R_CallMethodDef CallEntries[] = { {"_duckdb_rapi_rel_from_table_function", (DL_FUNC) &_duckdb_rapi_rel_from_table_function, 4}, {"_duckdb_rapi_rel_insert", (DL_FUNC) &_duckdb_rapi_rel_insert, 3}, {"_duckdb_rapi_rel_join", (DL_FUNC) &_duckdb_rapi_rel_join, 5}, + {"_duckdb_rapi_rel_join2", (DL_FUNC) &_duckdb_rapi_rel_join2, 6}, {"_duckdb_rapi_rel_limit", (DL_FUNC) &_duckdb_rapi_rel_limit, 2}, {"_duckdb_rapi_rel_names", (DL_FUNC) &_duckdb_rapi_rel_names, 1}, {"_duckdb_rapi_rel_order", (DL_FUNC) &_duckdb_rapi_rel_order, 3}, + {"_duckdb_rapi_rel_order2", (DL_FUNC) &_duckdb_rapi_rel_order2, 4}, {"_duckdb_rapi_rel_project", (DL_FUNC) &_duckdb_rapi_rel_project, 2}, {"_duckdb_rapi_rel_project2", (DL_FUNC) &_duckdb_rapi_rel_project2, 3}, {"_duckdb_rapi_rel_set_alias", (DL_FUNC) &_duckdb_rapi_rel_set_alias, 2}, From ba23cc0ce56b4af98f6e8e6a8f27cfd232971554 Mon Sep 17 00:00:00 2001 From: Antonov548 Date: Thu, 16 Jan 2025 12:22:48 +0100 Subject: [PATCH 31/69] add union_all2/limit2/distinct2 --- R/cpp11.R | 12 ++++++++++++ R/relational.R | 47 +++++++++++++++++++++++++++++++++++++++++---- R/rethrow-gen.R | 38 ++++++++++++++++++++++++++++++++---- src/cpp11.cpp | 24 +++++++++++++++++++++++ src/relational2.cpp | 28 +++++++++++++++++++++++++++ 5 files changed, 141 insertions(+), 8 deletions(-) diff --git a/R/cpp11.R b/R/cpp11.R index 297f4888a..ee831aaf4 100644 --- a/R/cpp11.R +++ b/R/cpp11.R @@ -208,6 +208,18 @@ rapi_rel_join2 <- function(left, right, con, conds, join, join_ref_type) { .Call(`_duckdb_rapi_rel_join2`, left, right, con, conds, join, join_ref_type) } +rapi_rel_union_all2 <- function(left, right, con) { + .Call(`_duckdb_rapi_rel_union_all2`, left, right, con) +} + +rapi_rel_limit2 <- function(df, con, n) { + .Call(`_duckdb_rapi_rel_limit2`, df, con, n) +} + +rapi_rel_distinct2 <- function(df, con) { + .Call(`_duckdb_rapi_rel_distinct2`, df, con) +} + rapi_rel_to_altrep <- function(rel, allow_materialization) { .Call(`_duckdb_rapi_rel_to_altrep`, rel, allow_materialization) } diff --git a/R/relational.R b/R/relational.R index 1115e8b49..864dc3f40 100644 --- a/R/relational.R +++ b/R/relational.R @@ -120,6 +120,19 @@ rel_limit <- function(rel, n) { rethrow_rapi_rel_limit(rel, n) } +#' Lazily retrieve the top-n rows of a DuckDB relation object +#' @param rel the DuckDB relation object +#' @param n the amount of rows to retrieve +#' @return the now limited `duckdb_relation` object +#' @noRd +#' @examples +#' con <- DBI::dbConnect(duckdb()) +#' rel <- rel_from_df(con, mtcars) +#' rel2 <- rel_limit(rel, 10) +rel_limit2 <- function(df, con, n) { + rethrow_rapi_rel_limit2(df, con@conn_ref, n) +} + #' Lazily project a DuckDB relation object #' @param rel the DuckDB relation object #' @param exprs a list of DuckDB expressions to project @@ -200,8 +213,8 @@ rel_aggregate <- function(rel, groups, aggregates) { #' rel <- rel_from_df(con, mtcars) #' aggrs <- list(avg_hp = expr_function("avg", list(expr_reference("hp")))) #' rel2 <- rel_aggregate(rel, list(expr_reference("cyl")), aggrs) -rel_aggregate2 <- function(rel, con, groups, aggregates) { - rethrow_rapi_rel_aggregate2(rel, con@conn_ref, groups, aggregates) +rel_aggregate2 <- function(df, con, groups, aggregates) { + rethrow_rapi_rel_aggregate2(df, con@conn_ref, groups, aggregates) } #' Lazily reorder a DuckDB relation object @@ -236,7 +249,7 @@ rel_order <- function(rel, orders, ascending = NULL) { #' con <- DBI::dbConnect(duckdb()) #' rel <- rel_from_df(con, mtcars) #' rel2 <- rel_order(rel, list(expr_reference("hp"))) -rel_order2 <- function(rel, con, orders, ascending = NULL) { +rel_order2 <- function(df, con, orders, ascending = NULL) { if (is.null(ascending)) { ascending <- rep(TRUE, length(orders)) } @@ -245,7 +258,7 @@ rel_order2 <- function(rel, con, orders, ascending = NULL) { stop("length of ascending must equal length of orders") } - return(rethrow_rapi_rel_order2(rel, con@conn_ref, orders, ascending)) + return(rethrow_rapi_rel_order2(df, con@conn_ref, orders, ascending)) } #' Get an external pointer pointing to NULL @@ -339,6 +352,20 @@ rel_union_all <- function(rel_a, rel_b) { rethrow_rapi_rel_union_all(rel_a, rel_b) } +#' UNION ALL on two DuckDB relation objects +#' @param rel_a a DuckDB relation object +#' @param rel_b a DuckDB relation object +#' @return a new `duckdb_relation` object resulting from the union +#' @noRd +#' @examples +#' con <- DBI::dbConnect(duckdb()) +#' rel_a <- rel_from_df(con, mtcars) +#' rel_b <- rel_from_df(con, mtcars) +#' rel_union_all(rel_a, rel_b) +rel_union_all2 <- function(df_a, df_b, con) { + rethrow_rapi_rel_union_all2(df_a, df_b, con@conn_ref) +} + #' Lazily compute a distinct result on a DuckDB relation object #' @param rel the input DuckDB relation object #' @return a new `duckdb_relation` object with distinct rows @@ -351,6 +378,18 @@ rel_distinct <- function(rel) { rethrow_rapi_rel_distinct(rel) } +#' Lazily compute a distinct result on a DuckDB relation object +#' @param rel the input DuckDB relation object +#' @return a new `duckdb_relation` object with distinct rows +#' @noRd +#' @examples +#' con <- DBI::dbConnect(duckdb()) +#' rel <- rel_from_df(con, mtcars) +#' rel2 <- rel_distinct(rel) +rel_distinct2 <- function(df, con) { + rethrow_rapi_rel_distinct(df, con@conn_ref) +} + #' SET INTERSECT on two DuckDB relation objects #' @param rel_a a DuckDB relation object #' @param rel_b a DuckDB relation object diff --git a/R/rethrow-gen.R b/R/rethrow-gen.R index 34eaaa3fc..223202507 100644 --- a/R/rethrow-gen.R +++ b/R/rethrow-gen.R @@ -216,9 +216,9 @@ rethrow_rapi_rel_aggregate <- function(rel, groups, aggregates, call = parent.fr ) } -rethrow_rapi_rel_aggregate2 <- function(rel, con, groups, aggregates, call = parent.frame(2)) { +rethrow_rapi_rel_aggregate2 <- function(df, con, groups, aggregates, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_aggregate2(rel, con, groups, aggregates), + rapi_rel_aggregate2(df, con, groups, aggregates), error = function(e) { rethrow_error_from_rapi(e, call) } @@ -234,9 +234,9 @@ rethrow_rapi_rel_order <- function(rel, orders, ascending, call = parent.frame(2 ) } -rethrow_rapi_rel_order2 <- function(rel, con, orders, ascending, call = parent.frame(2)) { +rethrow_rapi_rel_order2 <- function(df, con, orders, ascending, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_order2(rel, con, orders, ascending), + rapi_rel_order2(df, con, orders, ascending), error = function(e) { rethrow_error_from_rapi(e, call) } @@ -270,6 +270,15 @@ rethrow_rapi_rel_union_all <- function(rel_a, rel_b, call = parent.frame(2)) { ) } +rethrow_rapi_rel_union_all2 <- function(df_a, df_b, con, call = parent.frame(2)) { + rlang::try_fetch( + rapi_rel_union_all2(df_a, df_b, con), + error = function(e) { + rethrow_error_from_rapi(e, call) + } + ) +} + rethrow_rapi_rel_limit <- function(rel, n, call = parent.frame(2)) { rlang::try_fetch( rapi_rel_limit(rel, n), @@ -279,6 +288,15 @@ rethrow_rapi_rel_limit <- function(rel, n, call = parent.frame(2)) { ) } +rethrow_rapi_rel_limit2 <- function(df, con, n, call = parent.frame(2)) { + rlang::try_fetch( + rapi_rel_limit2(df, con, n), + error = function(e) { + rethrow_error_from_rapi(e, call) + } + ) +} + rethrow_rapi_rel_distinct <- function(rel, call = parent.frame(2)) { rlang::try_fetch( rapi_rel_distinct(rel), @@ -288,6 +306,15 @@ rethrow_rapi_rel_distinct <- function(rel, call = parent.frame(2)) { ) } +rethrow_rapi_rel_distinct2 <- function(df, con, call = parent.frame(2)) { + rlang::try_fetch( + rapi_rel_distinct2(df, con), + error = function(e) { + rethrow_error_from_rapi(e, call) + } + ) +} + rethrow_rapi_rel_to_df <- function(rel, call = parent.frame(2)) { rlang::try_fetch( rapi_rel_to_df(rel), @@ -625,8 +652,11 @@ rethrow_restore <- function() { rethrow_rapi_expr_window <<- rapi_expr_window rethrow_rapi_rel_join <<- rapi_rel_join rethrow_rapi_rel_union_all <<- rapi_rel_union_all + rethrow_rapi_rel_union_all2 <<- rapi_rel_union_all2 rethrow_rapi_rel_limit <<- rapi_rel_limit + rethrow_rapi_rel_limit2 <<- rapi_rel_limit2 rethrow_rapi_rel_distinct <<- rapi_rel_distinct + rethrow_rapi_rel_distinct2 <<- rapi_rel_distinct2 rethrow_rapi_rel_to_df <<- rapi_rel_to_df rethrow_rapi_rel_tostring <<- rapi_rel_tostring rethrow_rapi_rel_to_sql <<- rapi_rel_to_sql diff --git a/src/cpp11.cpp b/src/cpp11.cpp index 2bbcc318c..1b512bd48 100644 --- a/src/cpp11.cpp +++ b/src/cpp11.cpp @@ -381,6 +381,27 @@ extern "C" SEXP _duckdb_rapi_rel_join2(SEXP left, SEXP right, SEXP con, SEXP con return cpp11::as_sexp(rapi_rel_join2(cpp11::as_cpp>(left), cpp11::as_cpp>(right), cpp11::as_cpp>(con), cpp11::as_cpp>(conds), cpp11::as_cpp>(join), cpp11::as_cpp>(join_ref_type))); END_CPP11 } +// relational2.cpp +SEXP rapi_rel_union_all2(data_frame left, data_frame right, duckdb::conn_eptr_t con); +extern "C" SEXP _duckdb_rapi_rel_union_all2(SEXP left, SEXP right, SEXP con) { + BEGIN_CPP11 + return cpp11::as_sexp(rapi_rel_union_all2(cpp11::as_cpp>(left), cpp11::as_cpp>(right), cpp11::as_cpp>(con))); + END_CPP11 +} +// relational2.cpp +SEXP rapi_rel_limit2(data_frame df, duckdb::conn_eptr_t con, int64_t n); +extern "C" SEXP _duckdb_rapi_rel_limit2(SEXP df, SEXP con, SEXP n) { + BEGIN_CPP11 + return cpp11::as_sexp(rapi_rel_limit2(cpp11::as_cpp>(df), cpp11::as_cpp>(con), cpp11::as_cpp>(n))); + END_CPP11 +} +// relational2.cpp +SEXP rapi_rel_distinct2(data_frame df, duckdb::conn_eptr_t con); +extern "C" SEXP _duckdb_rapi_rel_distinct2(SEXP df, SEXP con) { + BEGIN_CPP11 + return cpp11::as_sexp(rapi_rel_distinct2(cpp11::as_cpp>(df), cpp11::as_cpp>(con))); + END_CPP11 +} // reltoaltrep.cpp SEXP rapi_rel_to_altrep(duckdb::rel_extptr_t rel, bool allow_materialization); extern "C" SEXP _duckdb_rapi_rel_to_altrep(SEXP rel, SEXP allow_materialization) { @@ -522,6 +543,7 @@ static const R_CallMethodDef CallEntries[] = { {"_duckdb_rapi_rel_aggregate2", (DL_FUNC) &_duckdb_rapi_rel_aggregate2, 4}, {"_duckdb_rapi_rel_alias", (DL_FUNC) &_duckdb_rapi_rel_alias, 1}, {"_duckdb_rapi_rel_distinct", (DL_FUNC) &_duckdb_rapi_rel_distinct, 1}, + {"_duckdb_rapi_rel_distinct2", (DL_FUNC) &_duckdb_rapi_rel_distinct2, 2}, {"_duckdb_rapi_rel_explain", (DL_FUNC) &_duckdb_rapi_rel_explain, 3}, {"_duckdb_rapi_rel_filter", (DL_FUNC) &_duckdb_rapi_rel_filter, 2}, {"_duckdb_rapi_rel_filter2", (DL_FUNC) &_duckdb_rapi_rel_filter2, 3}, @@ -534,6 +556,7 @@ static const R_CallMethodDef CallEntries[] = { {"_duckdb_rapi_rel_join", (DL_FUNC) &_duckdb_rapi_rel_join, 5}, {"_duckdb_rapi_rel_join2", (DL_FUNC) &_duckdb_rapi_rel_join2, 6}, {"_duckdb_rapi_rel_limit", (DL_FUNC) &_duckdb_rapi_rel_limit, 2}, + {"_duckdb_rapi_rel_limit2", (DL_FUNC) &_duckdb_rapi_rel_limit2, 3}, {"_duckdb_rapi_rel_names", (DL_FUNC) &_duckdb_rapi_rel_names, 1}, {"_duckdb_rapi_rel_order", (DL_FUNC) &_duckdb_rapi_rel_order, 3}, {"_duckdb_rapi_rel_order2", (DL_FUNC) &_duckdb_rapi_rel_order2, 4}, @@ -552,6 +575,7 @@ static const R_CallMethodDef CallEntries[] = { {"_duckdb_rapi_rel_to_table", (DL_FUNC) &_duckdb_rapi_rel_to_table, 4}, {"_duckdb_rapi_rel_tostring", (DL_FUNC) &_duckdb_rapi_rel_tostring, 2}, {"_duckdb_rapi_rel_union_all", (DL_FUNC) &_duckdb_rapi_rel_union_all, 2}, + {"_duckdb_rapi_rel_union_all2", (DL_FUNC) &_duckdb_rapi_rel_union_all2, 3}, {"_duckdb_rapi_release", (DL_FUNC) &_duckdb_rapi_release, 1}, {"_duckdb_rapi_shutdown", (DL_FUNC) &_duckdb_rapi_shutdown, 1}, {"_duckdb_rapi_startup", (DL_FUNC) &_duckdb_rapi_startup, 4}, diff --git a/src/relational2.cpp b/src/relational2.cpp index a9059bb1c..86574b261 100644 --- a/src/relational2.cpp +++ b/src/relational2.cpp @@ -186,3 +186,31 @@ using namespace cpp11; auto res = make_shared_ptr(rel_left->rel, rel_right->rel, std::move(cond), join_type, ref_type); return rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, std::move(res)), con, true); } + +[[cpp11::register]] SEXP rapi_rel_union_all2(data_frame left, data_frame right, duckdb::conn_eptr_t con) { + duckdb::rel_extptr_t rel_left = cpp11::as_cpp>(rapi_rel_from_any_df(con, left, true)); + duckdb::rel_extptr_t rel_right = cpp11::as_cpp>(rapi_rel_from_any_df(con, right, true)); + + cpp11::writable::list prot = {rel_left, rel_right}; + + auto setop = make_shared_ptr(rel_left->rel, rel_right->rel, SetOperationType::UNION); + setop->setop_all = true; + + return rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, std::move(setop)), con, true); +} + +[[cpp11::register]] SEXP rapi_rel_limit2(data_frame df, duckdb::conn_eptr_t con, int64_t n) { + duckdb::rel_extptr_t rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); + + cpp11::writable::list prot = {rel}; + + return rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, make_shared_ptr(rel->rel, n, 0)), con, true); +} + +[[cpp11::register]] SEXP rapi_rel_distinct2(data_frame df, duckdb::conn_eptr_t con) { + duckdb::rel_extptr_t rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); + + cpp11::writable::list prot = {rel}; + + return rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, make_shared_ptr(rel->rel)), con, true); +} From d9c117ec04e3268944aed6ddcbb8a2f1714289c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Fri, 17 Jan 2025 07:33:04 +0100 Subject: [PATCH 32/69] Reorder --- src/relational.cpp | 187 +++++++++++++++++++++++---------------------- 1 file changed, 96 insertions(+), 91 deletions(-) diff --git a/src/relational.cpp b/src/relational.cpp index 99f6cc72f..714d48604 100644 --- a/src/relational.cpp +++ b/src/relational.cpp @@ -119,7 +119,8 @@ using namespace cpp11; return expr->ToString(); } -// DuckDB Relations + +// DuckDB Relations: low-level conversion [[cpp11::register]] SEXP rapi_rel_from_df(duckdb::conn_eptr_t con, data_frame df, bool experimental) { if (!con || !con.get() || !con->conn) { @@ -152,6 +153,81 @@ SEXP rapi_rel_from_any_df(duckdb::conn_eptr_t con, SEXP df, bool allow_materiali return rapi_rel_from_df(con, df, false); } +static SEXP result_to_df(duckdb::unique_ptr res) { + if (res->HasError()) { + stop("%s", res->GetError().c_str()); + } + if (res->type == QueryResultType::STREAM_RESULT) { + res = ((StreamQueryResult &)*res).Materialize(); + } + D_ASSERT(res->type == QueryResultType::MATERIALIZED_RESULT); + auto mat_res = (MaterializedQueryResult *)res.get(); + + writable::integers row_names; + row_names.push_back(NA_INTEGER); + row_names.push_back(-mat_res->RowCount()); + + // TODO this thing we can probably statically cache + writable::strings classes; + classes.push_back("tbl_df"); + classes.push_back("tbl"); + classes.push_back("data.frame"); + + auto df = sexp(duckdb_execute_R_impl(mat_res, false)); + df.attr("class") = classes; + df.attr("row.names") = row_names; + return df; +} + +[[cpp11::register]] SEXP rapi_rel_to_df(duckdb::rel_extptr_t rel) { + ScopedInterruptHandler signal_handler(rel->rel->context->GetContext()); + + auto res = rel->rel->Execute(); + + if (signal_handler.HandleInterrupt()) { + return R_NilValue; + } + + signal_handler.Disable(); + + return result_to_df(std::move(res)); +} + + +// DuckDB Relations: questioning + +[[cpp11::register]] SEXP rapi_rel_sql(duckdb::rel_extptr_t rel, std::string sql) { + auto res = rel->rel->Query("_", sql); + if (res->HasError()) { + stop("%s", res->GetError().c_str()); + } + return result_to_df(std::move(res)); +} + + +// DuckDB Relations: names + +[[cpp11::register]] SEXP rapi_rel_names(duckdb::rel_extptr_t rel) { + auto ret = writable::strings(); + for (auto &col : rel->rel->Columns()) { + ret.push_back(col.Name()); + } + return (ret); +} + +[[cpp11::register]] std::string rapi_rel_alias(duckdb::rel_extptr_t rel) { + return rel->rel->GetAlias(); +} + +[[cpp11::register]] SEXP rapi_rel_set_alias(duckdb::rel_extptr_t rel, std::string alias) { + cpp11::writable::list prot = {rel}; + + return make_external_prot("duckdb_relation", prot, rel->rel->Alias(alias)); +} + + +// DuckDB Relations: operators + [[cpp11::register]] SEXP rapi_rel_filter(duckdb::rel_extptr_t rel, list exprs) { duckdb::unique_ptr filter_expr; if (exprs.size() == 0) { // nop @@ -375,32 +451,6 @@ bool constant_expression_is_not_null(duckdb::expr_extptr_t expr) { return make_external_prot("duckdb_relation", prot, res); } -static SEXP result_to_df(duckdb::unique_ptr res) { - if (res->HasError()) { - stop("%s", res->GetError().c_str()); - } - if (res->type == QueryResultType::STREAM_RESULT) { - res = ((StreamQueryResult &)*res).Materialize(); - } - D_ASSERT(res->type == QueryResultType::MATERIALIZED_RESULT); - auto mat_res = (MaterializedQueryResult *)res.get(); - - writable::integers row_names; - row_names.push_back(NA_INTEGER); - row_names.push_back(-mat_res->RowCount()); - - // TODO this thing we can probably statically cache - writable::strings classes; - classes.push_back("tbl_df"); - classes.push_back("tbl"); - classes.push_back("data.frame"); - - auto df = sexp(duckdb_execute_R_impl(mat_res, false)); - df.attr("class") = classes; - df.attr("row.names") = row_names; - return df; -} - [[cpp11::register]] SEXP rapi_rel_union_all(duckdb::rel_extptr_t rel_a, duckdb::rel_extptr_t rel_b) { auto res = make_shared_ptr(rel_a->rel, rel_b->rel, SetOperationType::UNION); res->setop_all = true; @@ -424,70 +474,6 @@ static SEXP result_to_df(duckdb::unique_ptr res) { return make_external_prot("duckdb_relation", prot, make_shared_ptr(rel->rel)); } -[[cpp11::register]] SEXP rapi_rel_to_df(duckdb::rel_extptr_t rel) { - ScopedInterruptHandler signal_handler(rel->rel->context->GetContext()); - - auto res = rel->rel->Execute(); - - if (signal_handler.HandleInterrupt()) { - return R_NilValue; - } - - signal_handler.Disable(); - - return result_to_df(std::move(res)); -} - -[[cpp11::register]] std::string rapi_rel_tostring(duckdb::rel_extptr_t rel, std::string format) { - if (format == "tree") { - return rel->rel->ToString(0); - } else { - return rel->rel->ToString(); - } -} - -[[cpp11::register]] std::string rapi_rel_to_sql(duckdb::rel_extptr_t rel) { - return rel->rel->GetQueryNode()->ToString(); -} - -[[cpp11::register]] SEXP rapi_rel_explain(duckdb::rel_extptr_t rel, std::string type, std::string format) { - auto type_enum = EnumUtil::FromString(type); - auto format_enum = EnumUtil::FromString(format); - return result_to_df(rel->rel->Explain(type_enum, format_enum)); -} - -[[cpp11::register]] std::string rapi_rel_alias(duckdb::rel_extptr_t rel) { - return rel->rel->GetAlias(); -} - -// Call this function to avoid passing an empty list if an argument is optional -[[cpp11::register]] SEXP rapi_get_null_SEXP_ptr() { - auto ret = make_external("duckdb_null_ptr", nullptr); - return ret; -} - -[[cpp11::register]] SEXP rapi_rel_set_alias(duckdb::rel_extptr_t rel, std::string alias) { - cpp11::writable::list prot = {rel}; - - return make_external_prot("duckdb_relation", prot, rel->rel->Alias(alias)); -} - -[[cpp11::register]] SEXP rapi_rel_sql(duckdb::rel_extptr_t rel, std::string sql) { - auto res = rel->rel->Query("_", sql); - if (res->HasError()) { - stop("%s", res->GetError().c_str()); - } - return result_to_df(std::move(res)); -} - -[[cpp11::register]] SEXP rapi_rel_names(duckdb::rel_extptr_t rel) { - auto ret = writable::strings(); - for (auto &col : rel->rel->Columns()) { - ret.push_back(col.Name()); - } - return (ret); -} - [[cpp11::register]] SEXP rapi_rel_set_intersect(duckdb::rel_extptr_t rel_a, duckdb::rel_extptr_t rel_b) { auto res = make_shared_ptr(rel_a->rel, rel_b->rel, SetOperationType::INTERSECT); @@ -568,6 +554,25 @@ static SEXP result_to_df(duckdb::unique_ptr res) { return make_external("duckdb_relation", std::move(rel)); } +[[cpp11::register]] std::string rapi_rel_tostring(duckdb::rel_extptr_t rel, std::string format) { + // FIXME: Support format = "sql" here, forwarding to rapi_rel_to_sql() + if (format == "tree") { + return rel->rel->ToString(0); + } else { + return rel->rel->ToString(); + } +} + +[[cpp11::register]] std::string rapi_rel_to_sql(duckdb::rel_extptr_t rel) { + return rel->rel->GetQueryNode()->ToString(); +} + +[[cpp11::register]] SEXP rapi_rel_explain(duckdb::rel_extptr_t rel, std::string type, std::string format) { + auto type_enum = EnumUtil::FromString(type); + auto format_enum = EnumUtil::FromString(format); + return result_to_df(rel->rel->Explain(type_enum, format_enum)); +} + [[cpp11::register]] void rapi_rel_to_parquet(duckdb::rel_extptr_t rel, std::string file_name, list options_sexps) { rel->rel->WriteParquet(file_name, ListToVectorOfValue(options_sexps)); } From 3a4c7265253c5e6a750af9ea33d234a6ca99c7fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Fri, 17 Jan 2025 07:34:20 +0100 Subject: [PATCH 33/69] Generate --- R/cpp11.R | 68 ++++++++++++++-------------- src/cpp11.cpp | 120 +++++++++++++++++++++++--------------------------- 2 files changed, 88 insertions(+), 100 deletions(-) diff --git a/R/cpp11.R b/R/cpp11.R index ee831aaf4..65609441b 100644 --- a/R/cpp11.R +++ b/R/cpp11.R @@ -76,6 +76,26 @@ rapi_rel_from_df <- function(con, df, experimental) { .Call(`_duckdb_rapi_rel_from_df`, con, df, experimental) } +rapi_rel_to_df <- function(rel) { + .Call(`_duckdb_rapi_rel_to_df`, rel) +} + +rapi_rel_sql <- function(rel, sql) { + .Call(`_duckdb_rapi_rel_sql`, rel, sql) +} + +rapi_rel_names <- function(rel) { + .Call(`_duckdb_rapi_rel_names`, rel) +} + +rapi_rel_alias <- function(rel) { + .Call(`_duckdb_rapi_rel_alias`, rel) +} + +rapi_rel_set_alias <- function(rel, alias) { + .Call(`_duckdb_rapi_rel_set_alias`, rel, alias) +} + rapi_rel_filter <- function(rel, exprs) { .Call(`_duckdb_rapi_rel_filter`, rel, exprs) } @@ -112,42 +132,6 @@ rapi_rel_distinct <- function(rel) { .Call(`_duckdb_rapi_rel_distinct`, rel) } -rapi_rel_to_df <- function(rel) { - .Call(`_duckdb_rapi_rel_to_df`, rel) -} - -rapi_rel_tostring <- function(rel, format) { - .Call(`_duckdb_rapi_rel_tostring`, rel, format) -} - -rapi_rel_to_sql <- function(rel) { - .Call(`_duckdb_rapi_rel_to_sql`, rel) -} - -rapi_rel_explain <- function(rel, type, format) { - .Call(`_duckdb_rapi_rel_explain`, rel, type, format) -} - -rapi_rel_alias <- function(rel) { - .Call(`_duckdb_rapi_rel_alias`, rel) -} - -rapi_get_null_SEXP_ptr <- function() { - .Call(`_duckdb_rapi_get_null_SEXP_ptr`) -} - -rapi_rel_set_alias <- function(rel, alias) { - .Call(`_duckdb_rapi_rel_set_alias`, rel, alias) -} - -rapi_rel_sql <- function(rel, sql) { - .Call(`_duckdb_rapi_rel_sql`, rel, sql) -} - -rapi_rel_names <- function(rel) { - .Call(`_duckdb_rapi_rel_names`, rel) -} - rapi_rel_set_intersect <- function(rel_a, rel_b) { .Call(`_duckdb_rapi_rel_set_intersect`, rel_a, rel_b) } @@ -172,6 +156,18 @@ rapi_rel_from_table_function <- function(con, function_name, positional_paramete .Call(`_duckdb_rapi_rel_from_table_function`, con, function_name, positional_parameters_sexps, named_parameters_sexps) } +rapi_rel_tostring <- function(rel, format) { + .Call(`_duckdb_rapi_rel_tostring`, rel, format) +} + +rapi_rel_to_sql <- function(rel) { + .Call(`_duckdb_rapi_rel_to_sql`, rel) +} + +rapi_rel_explain <- function(rel, type, format) { + .Call(`_duckdb_rapi_rel_explain`, rel, type, format) +} + rapi_rel_to_parquet <- function(rel, file_name, options_sexps) { invisible(.Call(`_duckdb_rapi_rel_to_parquet`, rel, file_name, options_sexps)) } diff --git a/src/cpp11.cpp b/src/cpp11.cpp index 1b512bd48..cbfd2241b 100644 --- a/src/cpp11.cpp +++ b/src/cpp11.cpp @@ -147,6 +147,41 @@ extern "C" SEXP _duckdb_rapi_rel_from_df(SEXP con, SEXP df, SEXP experimental) { END_CPP11 } // relational.cpp +SEXP rapi_rel_to_df(duckdb::rel_extptr_t rel); +extern "C" SEXP _duckdb_rapi_rel_to_df(SEXP rel) { + BEGIN_CPP11 + return cpp11::as_sexp(rapi_rel_to_df(cpp11::as_cpp>(rel))); + END_CPP11 +} +// relational.cpp +SEXP rapi_rel_sql(duckdb::rel_extptr_t rel, std::string sql); +extern "C" SEXP _duckdb_rapi_rel_sql(SEXP rel, SEXP sql) { + BEGIN_CPP11 + return cpp11::as_sexp(rapi_rel_sql(cpp11::as_cpp>(rel), cpp11::as_cpp>(sql))); + END_CPP11 +} +// relational.cpp +SEXP rapi_rel_names(duckdb::rel_extptr_t rel); +extern "C" SEXP _duckdb_rapi_rel_names(SEXP rel) { + BEGIN_CPP11 + return cpp11::as_sexp(rapi_rel_names(cpp11::as_cpp>(rel))); + END_CPP11 +} +// relational.cpp +std::string rapi_rel_alias(duckdb::rel_extptr_t rel); +extern "C" SEXP _duckdb_rapi_rel_alias(SEXP rel) { + BEGIN_CPP11 + return cpp11::as_sexp(rapi_rel_alias(cpp11::as_cpp>(rel))); + END_CPP11 +} +// relational.cpp +SEXP rapi_rel_set_alias(duckdb::rel_extptr_t rel, std::string alias); +extern "C" SEXP _duckdb_rapi_rel_set_alias(SEXP rel, SEXP alias) { + BEGIN_CPP11 + return cpp11::as_sexp(rapi_rel_set_alias(cpp11::as_cpp>(rel), cpp11::as_cpp>(alias))); + END_CPP11 +} +// relational.cpp SEXP rapi_rel_filter(duckdb::rel_extptr_t rel, list exprs); extern "C" SEXP _duckdb_rapi_rel_filter(SEXP rel, SEXP exprs) { BEGIN_CPP11 @@ -210,69 +245,6 @@ extern "C" SEXP _duckdb_rapi_rel_distinct(SEXP rel) { END_CPP11 } // relational.cpp -SEXP rapi_rel_to_df(duckdb::rel_extptr_t rel); -extern "C" SEXP _duckdb_rapi_rel_to_df(SEXP rel) { - BEGIN_CPP11 - return cpp11::as_sexp(rapi_rel_to_df(cpp11::as_cpp>(rel))); - END_CPP11 -} -// relational.cpp -std::string rapi_rel_tostring(duckdb::rel_extptr_t rel, std::string format); -extern "C" SEXP _duckdb_rapi_rel_tostring(SEXP rel, SEXP format) { - BEGIN_CPP11 - return cpp11::as_sexp(rapi_rel_tostring(cpp11::as_cpp>(rel), cpp11::as_cpp>(format))); - END_CPP11 -} -// relational.cpp -std::string rapi_rel_to_sql(duckdb::rel_extptr_t rel); -extern "C" SEXP _duckdb_rapi_rel_to_sql(SEXP rel) { - BEGIN_CPP11 - return cpp11::as_sexp(rapi_rel_to_sql(cpp11::as_cpp>(rel))); - END_CPP11 -} -// relational.cpp -SEXP rapi_rel_explain(duckdb::rel_extptr_t rel, std::string type, std::string format); -extern "C" SEXP _duckdb_rapi_rel_explain(SEXP rel, SEXP type, SEXP format) { - BEGIN_CPP11 - return cpp11::as_sexp(rapi_rel_explain(cpp11::as_cpp>(rel), cpp11::as_cpp>(type), cpp11::as_cpp>(format))); - END_CPP11 -} -// relational.cpp -std::string rapi_rel_alias(duckdb::rel_extptr_t rel); -extern "C" SEXP _duckdb_rapi_rel_alias(SEXP rel) { - BEGIN_CPP11 - return cpp11::as_sexp(rapi_rel_alias(cpp11::as_cpp>(rel))); - END_CPP11 -} -// relational.cpp -SEXP rapi_get_null_SEXP_ptr(); -extern "C" SEXP _duckdb_rapi_get_null_SEXP_ptr() { - BEGIN_CPP11 - return cpp11::as_sexp(rapi_get_null_SEXP_ptr()); - END_CPP11 -} -// relational.cpp -SEXP rapi_rel_set_alias(duckdb::rel_extptr_t rel, std::string alias); -extern "C" SEXP _duckdb_rapi_rel_set_alias(SEXP rel, SEXP alias) { - BEGIN_CPP11 - return cpp11::as_sexp(rapi_rel_set_alias(cpp11::as_cpp>(rel), cpp11::as_cpp>(alias))); - END_CPP11 -} -// relational.cpp -SEXP rapi_rel_sql(duckdb::rel_extptr_t rel, std::string sql); -extern "C" SEXP _duckdb_rapi_rel_sql(SEXP rel, SEXP sql) { - BEGIN_CPP11 - return cpp11::as_sexp(rapi_rel_sql(cpp11::as_cpp>(rel), cpp11::as_cpp>(sql))); - END_CPP11 -} -// relational.cpp -SEXP rapi_rel_names(duckdb::rel_extptr_t rel); -extern "C" SEXP _duckdb_rapi_rel_names(SEXP rel) { - BEGIN_CPP11 - return cpp11::as_sexp(rapi_rel_names(cpp11::as_cpp>(rel))); - END_CPP11 -} -// relational.cpp SEXP rapi_rel_set_intersect(duckdb::rel_extptr_t rel_a, duckdb::rel_extptr_t rel_b); extern "C" SEXP _duckdb_rapi_rel_set_intersect(SEXP rel_a, SEXP rel_b) { BEGIN_CPP11 @@ -315,6 +287,27 @@ extern "C" SEXP _duckdb_rapi_rel_from_table_function(SEXP con, SEXP function_nam END_CPP11 } // relational.cpp +std::string rapi_rel_tostring(duckdb::rel_extptr_t rel, std::string format); +extern "C" SEXP _duckdb_rapi_rel_tostring(SEXP rel, SEXP format) { + BEGIN_CPP11 + return cpp11::as_sexp(rapi_rel_tostring(cpp11::as_cpp>(rel), cpp11::as_cpp>(format))); + END_CPP11 +} +// relational.cpp +std::string rapi_rel_to_sql(duckdb::rel_extptr_t rel); +extern "C" SEXP _duckdb_rapi_rel_to_sql(SEXP rel) { + BEGIN_CPP11 + return cpp11::as_sexp(rapi_rel_to_sql(cpp11::as_cpp>(rel))); + END_CPP11 +} +// relational.cpp +SEXP rapi_rel_explain(duckdb::rel_extptr_t rel, std::string type, std::string format); +extern "C" SEXP _duckdb_rapi_rel_explain(SEXP rel, SEXP type, SEXP format) { + BEGIN_CPP11 + return cpp11::as_sexp(rapi_rel_explain(cpp11::as_cpp>(rel), cpp11::as_cpp>(type), cpp11::as_cpp>(format))); + END_CPP11 +} +// relational.cpp void rapi_rel_to_parquet(duckdb::rel_extptr_t rel, std::string file_name, list options_sexps); extern "C" SEXP _duckdb_rapi_rel_to_parquet(SEXP rel, SEXP file_name, SEXP options_sexps) { BEGIN_CPP11 @@ -525,7 +518,6 @@ static const R_CallMethodDef CallEntries[] = { {"_duckdb_rapi_expr_set_alias", (DL_FUNC) &_duckdb_rapi_expr_set_alias, 2}, {"_duckdb_rapi_expr_tostring", (DL_FUNC) &_duckdb_rapi_expr_tostring, 1}, {"_duckdb_rapi_expr_window", (DL_FUNC) &_duckdb_rapi_expr_window, 9}, - {"_duckdb_rapi_get_null_SEXP_ptr", (DL_FUNC) &_duckdb_rapi_get_null_SEXP_ptr, 0}, {"_duckdb_rapi_get_substrait", (DL_FUNC) &_duckdb_rapi_get_substrait, 3}, {"_duckdb_rapi_get_substrait_json", (DL_FUNC) &_duckdb_rapi_get_substrait_json, 3}, {"_duckdb_rapi_is_locked", (DL_FUNC) &_duckdb_rapi_is_locked, 1}, From 892d069a4d989bb8c1aa1e87b0a94995f6913019 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Fri, 17 Jan 2025 07:35:02 +0100 Subject: [PATCH 34/69] Reorder --- src/relational2.cpp | 46 ++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/src/relational2.cpp b/src/relational2.cpp index 86574b261..7a952e51b 100644 --- a/src/relational2.cpp +++ b/src/relational2.cpp @@ -29,29 +29,6 @@ using namespace cpp11; // DuckDB Expressions -[[cpp11::register]] SEXP rapi_rel_project2(data_frame df, duckdb::conn_eptr_t con, list exprs) { - if (exprs.size() == 0) { - stop("expected projection expressions"); - } - vector> projections; - vector aliases; - - for (expr_extptr_t expr : exprs) { - auto dexpr = expr->Copy(); - aliases.push_back(dexpr->GetName()); - projections.push_back(std::move(dexpr)); - } - - - duckdb::rel_extptr_t rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); - - auto projection = make_shared_ptr(rel->rel, std::move(projections), std::move(aliases)); - - cpp11::writable::list prot = {rel}; - - return rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, std::move(projection)), con, true); -} - [[cpp11::register]] SEXP rapi_rel_filter2(data_frame df, duckdb::conn_eptr_t con, list exprs) { duckdb::unique_ptr filter_expr; if (exprs.size() == 0) { // nop @@ -75,6 +52,29 @@ using namespace cpp11; return rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, std::move(filter)), con, true); } +[[cpp11::register]] SEXP rapi_rel_project2(data_frame df, duckdb::conn_eptr_t con, list exprs) { + if (exprs.size() == 0) { + stop("expected projection expressions"); + } + vector> projections; + vector aliases; + + for (expr_extptr_t expr : exprs) { + auto dexpr = expr->Copy(); + aliases.push_back(dexpr->GetName()); + projections.push_back(std::move(dexpr)); + } + + + duckdb::rel_extptr_t rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); + + auto projection = make_shared_ptr(rel->rel, std::move(projections), std::move(aliases)); + + cpp11::writable::list prot = {rel}; + + return rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, std::move(projection)), con, true); +} + [[cpp11::register]] SEXP rapi_rel_aggregate2(data_frame df, duckdb::conn_eptr_t con, list groups, list aggregates) { vector> res_groups, res_aggregates; From 6419a0d6ce7c3bfbca312dc54eda2855ff8597d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Fri, 17 Jan 2025 07:35:18 +0100 Subject: [PATCH 35/69] Generate --- R/cpp11.R | 8 ++++---- src/cpp11.cpp | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/R/cpp11.R b/R/cpp11.R index 65609441b..257e88f79 100644 --- a/R/cpp11.R +++ b/R/cpp11.R @@ -184,14 +184,14 @@ rapi_rel_insert <- function(rel, schema_name, table_name) { invisible(.Call(`_duckdb_rapi_rel_insert`, rel, schema_name, table_name)) } -rapi_rel_project2 <- function(df, con, exprs) { - .Call(`_duckdb_rapi_rel_project2`, df, con, exprs) -} - rapi_rel_filter2 <- function(df, con, exprs) { .Call(`_duckdb_rapi_rel_filter2`, df, con, exprs) } +rapi_rel_project2 <- function(df, con, exprs) { + .Call(`_duckdb_rapi_rel_project2`, df, con, exprs) +} + rapi_rel_aggregate2 <- function(df, con, groups, aggregates) { .Call(`_duckdb_rapi_rel_aggregate2`, df, con, groups, aggregates) } diff --git a/src/cpp11.cpp b/src/cpp11.cpp index cbfd2241b..5b9a9b86b 100644 --- a/src/cpp11.cpp +++ b/src/cpp11.cpp @@ -340,17 +340,17 @@ extern "C" SEXP _duckdb_rapi_rel_insert(SEXP rel, SEXP schema_name, SEXP table_n END_CPP11 } // relational2.cpp -SEXP rapi_rel_project2(data_frame df, duckdb::conn_eptr_t con, list exprs); -extern "C" SEXP _duckdb_rapi_rel_project2(SEXP df, SEXP con, SEXP exprs) { +SEXP rapi_rel_filter2(data_frame df, duckdb::conn_eptr_t con, list exprs); +extern "C" SEXP _duckdb_rapi_rel_filter2(SEXP df, SEXP con, SEXP exprs) { BEGIN_CPP11 - return cpp11::as_sexp(rapi_rel_project2(cpp11::as_cpp>(df), cpp11::as_cpp>(con), cpp11::as_cpp>(exprs))); + return cpp11::as_sexp(rapi_rel_filter2(cpp11::as_cpp>(df), cpp11::as_cpp>(con), cpp11::as_cpp>(exprs))); END_CPP11 } // relational2.cpp -SEXP rapi_rel_filter2(data_frame df, duckdb::conn_eptr_t con, list exprs); -extern "C" SEXP _duckdb_rapi_rel_filter2(SEXP df, SEXP con, SEXP exprs) { +SEXP rapi_rel_project2(data_frame df, duckdb::conn_eptr_t con, list exprs); +extern "C" SEXP _duckdb_rapi_rel_project2(SEXP df, SEXP con, SEXP exprs) { BEGIN_CPP11 - return cpp11::as_sexp(rapi_rel_filter2(cpp11::as_cpp>(df), cpp11::as_cpp>(con), cpp11::as_cpp>(exprs))); + return cpp11::as_sexp(rapi_rel_project2(cpp11::as_cpp>(df), cpp11::as_cpp>(con), cpp11::as_cpp>(exprs))); END_CPP11 } // relational2.cpp From e63b8c2a3a04fb2a6c13d429694033d28ea7ca10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Fri, 17 Jan 2025 07:52:58 +0100 Subject: [PATCH 36/69] Anchor --- src/relational.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/relational.cpp b/src/relational.cpp index 714d48604..3e3234671 100644 --- a/src/relational.cpp +++ b/src/relational.cpp @@ -502,6 +502,9 @@ bool constant_expression_is_not_null(duckdb::expr_extptr_t expr) { return make_external_prot("duckdb_relation", prot, symdiff); } + +// DuckDB Relations: conversion + [[cpp11::register]] SEXP rapi_rel_from_sql(duckdb::conn_eptr_t con, const std::string sql) { if (!con || !con.get() || !con->conn) { stop("rel_from_table: Invalid connection"); From dce300d614bf2e604927baaf9175f6a22f548fd2 Mon Sep 17 00:00:00 2001 From: Antonov548 Date: Mon, 20 Jan 2025 10:19:26 +0100 Subject: [PATCH 37/69] add names functions --- R/cpp11.R | 16 ++++++++++++++++ src/cpp11.cpp | 32 ++++++++++++++++++++++++++++++++ src/relational.cpp | 5 +++++ src/relational2.cpp | 44 ++++++++++++++++++++++++++++++++++---------- 4 files changed, 87 insertions(+), 10 deletions(-) diff --git a/R/cpp11.R b/R/cpp11.R index 257e88f79..abb7dfad9 100644 --- a/R/cpp11.R +++ b/R/cpp11.R @@ -72,6 +72,10 @@ rapi_expr_tostring <- function(expr) { .Call(`_duckdb_rapi_expr_tostring`, expr) } +rapi_get_null_SEXP_ptr <- function() { + .Call(`_duckdb_rapi_get_null_SEXP_ptr`) +} + rapi_rel_from_df <- function(con, df, experimental) { .Call(`_duckdb_rapi_rel_from_df`, con, df, experimental) } @@ -216,6 +220,18 @@ rapi_rel_distinct2 <- function(df, con) { .Call(`_duckdb_rapi_rel_distinct2`, df, con) } +rapi_rel_names2 <- function(df, con) { + .Call(`_duckdb_rapi_rel_names2`, df, con) +} + +rapi_rel_alias2 <- function(df, con) { + .Call(`_duckdb_rapi_rel_alias2`, df, con) +} + +rapi_rel_set_alias2 <- function(df, con, alias) { + .Call(`_duckdb_rapi_rel_set_alias2`, df, con, alias) +} + rapi_rel_to_altrep <- function(rel, allow_materialization) { .Call(`_duckdb_rapi_rel_to_altrep`, rel, allow_materialization) } diff --git a/src/cpp11.cpp b/src/cpp11.cpp index 5b9a9b86b..7a6de617d 100644 --- a/src/cpp11.cpp +++ b/src/cpp11.cpp @@ -140,6 +140,13 @@ extern "C" SEXP _duckdb_rapi_expr_tostring(SEXP expr) { END_CPP11 } // relational.cpp +SEXP rapi_get_null_SEXP_ptr(); +extern "C" SEXP _duckdb_rapi_get_null_SEXP_ptr() { + BEGIN_CPP11 + return cpp11::as_sexp(rapi_get_null_SEXP_ptr()); + END_CPP11 +} +// relational.cpp SEXP rapi_rel_from_df(duckdb::conn_eptr_t con, data_frame df, bool experimental); extern "C" SEXP _duckdb_rapi_rel_from_df(SEXP con, SEXP df, SEXP experimental) { BEGIN_CPP11 @@ -395,6 +402,27 @@ extern "C" SEXP _duckdb_rapi_rel_distinct2(SEXP df, SEXP con) { return cpp11::as_sexp(rapi_rel_distinct2(cpp11::as_cpp>(df), cpp11::as_cpp>(con))); END_CPP11 } +// relational2.cpp +SEXP rapi_rel_names2(data_frame df, duckdb::conn_eptr_t con); +extern "C" SEXP _duckdb_rapi_rel_names2(SEXP df, SEXP con) { + BEGIN_CPP11 + return cpp11::as_sexp(rapi_rel_names2(cpp11::as_cpp>(df), cpp11::as_cpp>(con))); + END_CPP11 +} +// relational2.cpp +std::string rapi_rel_alias2(data_frame df, duckdb::conn_eptr_t con); +extern "C" SEXP _duckdb_rapi_rel_alias2(SEXP df, SEXP con) { + BEGIN_CPP11 + return cpp11::as_sexp(rapi_rel_alias2(cpp11::as_cpp>(df), cpp11::as_cpp>(con))); + END_CPP11 +} +// relational2.cpp +SEXP rapi_rel_set_alias2(data_frame df, duckdb::conn_eptr_t con, std::string alias); +extern "C" SEXP _duckdb_rapi_rel_set_alias2(SEXP df, SEXP con, SEXP alias) { + BEGIN_CPP11 + return cpp11::as_sexp(rapi_rel_set_alias2(cpp11::as_cpp>(df), cpp11::as_cpp>(con), cpp11::as_cpp>(alias))); + END_CPP11 +} // reltoaltrep.cpp SEXP rapi_rel_to_altrep(duckdb::rel_extptr_t rel, bool allow_materialization); extern "C" SEXP _duckdb_rapi_rel_to_altrep(SEXP rel, SEXP allow_materialization) { @@ -518,6 +546,7 @@ static const R_CallMethodDef CallEntries[] = { {"_duckdb_rapi_expr_set_alias", (DL_FUNC) &_duckdb_rapi_expr_set_alias, 2}, {"_duckdb_rapi_expr_tostring", (DL_FUNC) &_duckdb_rapi_expr_tostring, 1}, {"_duckdb_rapi_expr_window", (DL_FUNC) &_duckdb_rapi_expr_window, 9}, + {"_duckdb_rapi_get_null_SEXP_ptr", (DL_FUNC) &_duckdb_rapi_get_null_SEXP_ptr, 0}, {"_duckdb_rapi_get_substrait", (DL_FUNC) &_duckdb_rapi_get_substrait, 3}, {"_duckdb_rapi_get_substrait_json", (DL_FUNC) &_duckdb_rapi_get_substrait_json, 3}, {"_duckdb_rapi_is_locked", (DL_FUNC) &_duckdb_rapi_is_locked, 1}, @@ -534,6 +563,7 @@ static const R_CallMethodDef CallEntries[] = { {"_duckdb_rapi_rel_aggregate", (DL_FUNC) &_duckdb_rapi_rel_aggregate, 3}, {"_duckdb_rapi_rel_aggregate2", (DL_FUNC) &_duckdb_rapi_rel_aggregate2, 4}, {"_duckdb_rapi_rel_alias", (DL_FUNC) &_duckdb_rapi_rel_alias, 1}, + {"_duckdb_rapi_rel_alias2", (DL_FUNC) &_duckdb_rapi_rel_alias2, 2}, {"_duckdb_rapi_rel_distinct", (DL_FUNC) &_duckdb_rapi_rel_distinct, 1}, {"_duckdb_rapi_rel_distinct2", (DL_FUNC) &_duckdb_rapi_rel_distinct2, 2}, {"_duckdb_rapi_rel_explain", (DL_FUNC) &_duckdb_rapi_rel_explain, 3}, @@ -550,11 +580,13 @@ static const R_CallMethodDef CallEntries[] = { {"_duckdb_rapi_rel_limit", (DL_FUNC) &_duckdb_rapi_rel_limit, 2}, {"_duckdb_rapi_rel_limit2", (DL_FUNC) &_duckdb_rapi_rel_limit2, 3}, {"_duckdb_rapi_rel_names", (DL_FUNC) &_duckdb_rapi_rel_names, 1}, + {"_duckdb_rapi_rel_names2", (DL_FUNC) &_duckdb_rapi_rel_names2, 2}, {"_duckdb_rapi_rel_order", (DL_FUNC) &_duckdb_rapi_rel_order, 3}, {"_duckdb_rapi_rel_order2", (DL_FUNC) &_duckdb_rapi_rel_order2, 4}, {"_duckdb_rapi_rel_project", (DL_FUNC) &_duckdb_rapi_rel_project, 2}, {"_duckdb_rapi_rel_project2", (DL_FUNC) &_duckdb_rapi_rel_project2, 3}, {"_duckdb_rapi_rel_set_alias", (DL_FUNC) &_duckdb_rapi_rel_set_alias, 2}, + {"_duckdb_rapi_rel_set_alias2", (DL_FUNC) &_duckdb_rapi_rel_set_alias2, 3}, {"_duckdb_rapi_rel_set_diff", (DL_FUNC) &_duckdb_rapi_rel_set_diff, 2}, {"_duckdb_rapi_rel_set_intersect", (DL_FUNC) &_duckdb_rapi_rel_set_intersect, 2}, {"_duckdb_rapi_rel_set_symdiff", (DL_FUNC) &_duckdb_rapi_rel_set_symdiff, 2}, diff --git a/src/relational.cpp b/src/relational.cpp index 3e3234671..e01142447 100644 --- a/src/relational.cpp +++ b/src/relational.cpp @@ -122,6 +122,11 @@ using namespace cpp11; // DuckDB Relations: low-level conversion +[[cpp11::register]] SEXP rapi_get_null_SEXP_ptr() { + auto ret = make_external("duckdb_null_ptr", nullptr); + return ret; +} + [[cpp11::register]] SEXP rapi_rel_from_df(duckdb::conn_eptr_t con, data_frame df, bool experimental) { if (!con || !con.get() || !con->conn) { stop("rel_from_df: Invalid connection"); diff --git a/src/relational2.cpp b/src/relational2.cpp index 7a952e51b..6de0fe671 100644 --- a/src/relational2.cpp +++ b/src/relational2.cpp @@ -43,7 +43,7 @@ using namespace cpp11; } filter_expr = make_uniq(ExpressionType::CONJUNCTION_AND, std::move(filters)); } - duckdb::rel_extptr_t rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); + auto rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); auto filter = make_shared_ptr(rel->rel, std::move(filter_expr)); @@ -66,7 +66,7 @@ using namespace cpp11; } - duckdb::rel_extptr_t rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); + auto rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); auto projection = make_shared_ptr(rel->rel, std::move(projections), std::move(aliases)); @@ -97,7 +97,7 @@ using namespace cpp11; res_aggregates.push_back(std::move(expr)); aggr_idx++; } - duckdb::rel_extptr_t rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); + auto rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); auto aggregate = make_shared_ptr(rel->rel, std::move(res_aggregates), std::move(res_groups)); @@ -118,7 +118,7 @@ using namespace cpp11; res_orders.emplace_back(order_type, OrderByNullType::NULLS_LAST, expr->Copy()); } - duckdb::rel_extptr_t rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); + auto rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); auto order = make_shared_ptr(rel->rel, std::move(res_orders)); @@ -143,8 +143,8 @@ using namespace cpp11; ref_type = JoinRefType::ASOF; } - duckdb::rel_extptr_t rel_left = cpp11::as_cpp>(rapi_rel_from_any_df(con, left, true)); - duckdb::rel_extptr_t rel_right = cpp11::as_cpp>(rapi_rel_from_any_df(con, right, true)); + auto rel_left = cpp11::as_cpp>(rapi_rel_from_any_df(con, left, true)); + auto rel_right = cpp11::as_cpp>(rapi_rel_from_any_df(con, right, true)); cpp11::writable::list prot = {rel_left, rel_right}; @@ -188,8 +188,8 @@ using namespace cpp11; } [[cpp11::register]] SEXP rapi_rel_union_all2(data_frame left, data_frame right, duckdb::conn_eptr_t con) { - duckdb::rel_extptr_t rel_left = cpp11::as_cpp>(rapi_rel_from_any_df(con, left, true)); - duckdb::rel_extptr_t rel_right = cpp11::as_cpp>(rapi_rel_from_any_df(con, right, true)); + auto rel_left = cpp11::as_cpp>(rapi_rel_from_any_df(con, left, true)); + auto rel_right = cpp11::as_cpp>(rapi_rel_from_any_df(con, right, true)); cpp11::writable::list prot = {rel_left, rel_right}; @@ -200,7 +200,7 @@ using namespace cpp11; } [[cpp11::register]] SEXP rapi_rel_limit2(data_frame df, duckdb::conn_eptr_t con, int64_t n) { - duckdb::rel_extptr_t rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); + auto rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); cpp11::writable::list prot = {rel}; @@ -208,9 +208,33 @@ using namespace cpp11; } [[cpp11::register]] SEXP rapi_rel_distinct2(data_frame df, duckdb::conn_eptr_t con) { - duckdb::rel_extptr_t rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); + auto rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); cpp11::writable::list prot = {rel}; return rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, make_shared_ptr(rel->rel)), con, true); } + +// DuckDB Relations: names + +[[cpp11::register]] SEXP rapi_rel_names2(data_frame df, duckdb::conn_eptr_t con) { + auto rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); + + auto ret = writable::strings(); + for (auto &col : rel->rel->Columns()) { + ret.push_back(col.Name()); + } + return (ret); +} + +[[cpp11::register]] std::string rapi_rel_alias2(data_frame df, duckdb::conn_eptr_t con) { + auto rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); + return rel->rel->GetAlias(); +} + +[[cpp11::register]] SEXP rapi_rel_set_alias2(data_frame df, duckdb::conn_eptr_t con, std::string alias) { + auto rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); + cpp11::writable::list prot = {rel}; + + return make_external_prot("duckdb_relation", prot, rel->rel->Alias(alias)); +} From 908df890e50e4bb815499009868bdc6e37170f98 Mon Sep 17 00:00:00 2001 From: Antonov548 Date: Mon, 20 Jan 2025 10:34:44 +0100 Subject: [PATCH 38/69] use generated rethrow --- R/relational.R | 27 +++++++ R/rethrow-gen.R | 188 +++++++++++++++++++++++++++++------------------- 2 files changed, 141 insertions(+), 74 deletions(-) diff --git a/R/relational.R b/R/relational.R index 864dc3f40..2ad3eb77f 100644 --- a/R/relational.R +++ b/R/relational.R @@ -507,6 +507,29 @@ rel_set_alias <- function(rel, alias) { rethrow_rapi_rel_set_alias(rel, alias) } +#' Get the internal alias for a DuckDB relation object +#' @param rel the DuckDB relation object +#' @noRd +#' @examples +#' con <- DBI::dbConnect(duckdb()) +#' rel <- rel_from_df(con, mtcars) +#' rel_alias(rel) +rel_alias2 <- function(rel) { + rethrow_rapi_rel_alias2(rel) +} + +#' Set the internal alias for a DuckDB relation object +#' @param rel the DuckDB relation object +#' @param alias the new alias +#' @noRd +#' @examples +#' con <- DBI::dbConnect(duckdb()) +#' rel <- rel_from_df(con, mtcars) +#' rel_set_alias(rel, "my_new_alias") +rel_set_alias2 <- function(rel, alias) { + rethrow_rapi_rel_set_alias2(rel, alias) +} + #' Transforms a relation object to a lazy data frame using altrep #' @param rel the DuckDB relation object #' @return a data frame @@ -615,6 +638,10 @@ rel_names <- function(rel) { rethrow_rapi_rel_names(rel) } +rel_names2 <- function(rel) { + rethrow_rapi_rel_names2(rel) +} + load_rfuns <- function() { rethrow_rapi_load_rfuns() } diff --git a/R/rethrow-gen.R b/R/rethrow-gen.R index 223202507..aeee08c6c 100644 --- a/R/rethrow-gen.R +++ b/R/rethrow-gen.R @@ -162,6 +162,15 @@ rethrow_rapi_expr_tostring <- function(expr, call = parent.frame(2)) { ) } +rethrow_rapi_get_null_SEXP_ptr <- function(call = parent.frame(2)) { + rlang::try_fetch( + rapi_get_null_SEXP_ptr(), + error = function(e) { + rethrow_error_from_rapi(e, call) + } + ) +} + rethrow_rapi_rel_from_df <- function(con, df, experimental, call = parent.frame(2)) { rlang::try_fetch( rapi_rel_from_df(con, df, experimental), @@ -171,72 +180,81 @@ rethrow_rapi_rel_from_df <- function(con, df, experimental, call = parent.frame( ) } -rethrow_rapi_rel_filter <- function(rel, exprs, call = parent.frame(2)) { +rethrow_rapi_rel_to_df <- function(rel, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_filter(rel, exprs), + rapi_rel_to_df(rel), error = function(e) { rethrow_error_from_rapi(e, call) } ) } -rethrow_rapi_rel_filter2 <- function(df, con, exprs, call = parent.frame(2)) { +rethrow_rapi_rel_sql <- function(rel, sql, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_filter2(df, con, exprs), + rapi_rel_sql(rel, sql), error = function(e) { rethrow_error_from_rapi(e, call) } ) } -rethrow_rapi_rel_project <- function(rel, exprs, call = parent.frame(2)) { +rethrow_rapi_rel_names <- function(rel, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_project(rel, exprs), + rapi_rel_names(rel), error = function(e) { rethrow_error_from_rapi(e, call) } ) } -rethrow_rapi_rel_project2 <- function(df, con, exprs, call = parent.frame(2)) { +rethrow_rapi_rel_alias <- function(rel, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_project2(df, con, exprs), + rapi_rel_alias(rel), error = function(e) { rethrow_error_from_rapi(e, call) } ) } -rethrow_rapi_rel_aggregate <- function(rel, groups, aggregates, call = parent.frame(2)) { +rethrow_rapi_rel_set_alias <- function(rel, alias, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_aggregate(rel, groups, aggregates), + rapi_rel_set_alias(rel, alias), error = function(e) { rethrow_error_from_rapi(e, call) } ) } -rethrow_rapi_rel_aggregate2 <- function(df, con, groups, aggregates, call = parent.frame(2)) { +rethrow_rapi_rel_filter <- function(rel, exprs, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_aggregate2(df, con, groups, aggregates), + rapi_rel_filter(rel, exprs), error = function(e) { rethrow_error_from_rapi(e, call) } ) } -rethrow_rapi_rel_order <- function(rel, orders, ascending, call = parent.frame(2)) { +rethrow_rapi_rel_project <- function(rel, exprs, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_order(rel, orders, ascending), + rapi_rel_project(rel, exprs), error = function(e) { rethrow_error_from_rapi(e, call) } ) } -rethrow_rapi_rel_order2 <- function(df, con, orders, ascending, call = parent.frame(2)) { +rethrow_rapi_rel_aggregate <- function(rel, groups, aggregates, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_order2(df, con, orders, ascending), + rapi_rel_aggregate(rel, groups, aggregates), + error = function(e) { + rethrow_error_from_rapi(e, call) + } + ) +} + +rethrow_rapi_rel_order <- function(rel, orders, ascending, call = parent.frame(2)) { + rlang::try_fetch( + rapi_rel_order(rel, orders, ascending), error = function(e) { rethrow_error_from_rapi(e, call) } @@ -270,54 +288,72 @@ rethrow_rapi_rel_union_all <- function(rel_a, rel_b, call = parent.frame(2)) { ) } -rethrow_rapi_rel_union_all2 <- function(df_a, df_b, con, call = parent.frame(2)) { +rethrow_rapi_rel_limit <- function(rel, n, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_union_all2(df_a, df_b, con), + rapi_rel_limit(rel, n), error = function(e) { rethrow_error_from_rapi(e, call) } ) } -rethrow_rapi_rel_limit <- function(rel, n, call = parent.frame(2)) { +rethrow_rapi_rel_distinct <- function(rel, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_limit(rel, n), + rapi_rel_distinct(rel), error = function(e) { rethrow_error_from_rapi(e, call) } ) } -rethrow_rapi_rel_limit2 <- function(df, con, n, call = parent.frame(2)) { +rethrow_rapi_rel_set_intersect <- function(rel_a, rel_b, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_limit2(df, con, n), + rapi_rel_set_intersect(rel_a, rel_b), error = function(e) { rethrow_error_from_rapi(e, call) } ) } -rethrow_rapi_rel_distinct <- function(rel, call = parent.frame(2)) { +rethrow_rapi_rel_set_diff <- function(rel_a, rel_b, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_distinct(rel), + rapi_rel_set_diff(rel_a, rel_b), error = function(e) { rethrow_error_from_rapi(e, call) } ) } -rethrow_rapi_rel_distinct2 <- function(df, con, call = parent.frame(2)) { +rethrow_rapi_rel_set_symdiff <- function(rel_a, rel_b, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_distinct2(df, con), + rapi_rel_set_symdiff(rel_a, rel_b), error = function(e) { rethrow_error_from_rapi(e, call) } ) } -rethrow_rapi_rel_to_df <- function(rel, call = parent.frame(2)) { +rethrow_rapi_rel_from_sql <- function(con, sql, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_to_df(rel), + rapi_rel_from_sql(con, sql), + error = function(e) { + rethrow_error_from_rapi(e, call) + } + ) +} + +rethrow_rapi_rel_from_table <- function(con, schema_name, table_name, call = parent.frame(2)) { + rlang::try_fetch( + rapi_rel_from_table(con, schema_name, table_name), + error = function(e) { + rethrow_error_from_rapi(e, call) + } + ) +} + +rethrow_rapi_rel_from_table_function <- function(con, function_name, positional_parameters_sexps, named_parameters_sexps, call = parent.frame(2)) { + rlang::try_fetch( + rapi_rel_from_table_function(con, function_name, positional_parameters_sexps, named_parameters_sexps), error = function(e) { rethrow_error_from_rapi(e, call) } @@ -351,135 +387,135 @@ rethrow_rapi_rel_explain <- function(rel, type, format, call = parent.frame(2)) ) } -rethrow_rapi_rel_alias <- function(rel, call = parent.frame(2)) { +rethrow_rapi_rel_to_parquet <- function(rel, file_name, options_sexps, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_alias(rel), + rapi_rel_to_parquet(rel, file_name, options_sexps), error = function(e) { rethrow_error_from_rapi(e, call) } ) } -rethrow_rapi_get_null_SEXP_ptr <- function(call = parent.frame(2)) { +rethrow_rapi_rel_to_csv <- function(rel, file_name, options_sexps, call = parent.frame(2)) { rlang::try_fetch( - rapi_get_null_SEXP_ptr(), + rapi_rel_to_csv(rel, file_name, options_sexps), error = function(e) { rethrow_error_from_rapi(e, call) } ) } -rethrow_rapi_rel_set_alias <- function(rel, alias, call = parent.frame(2)) { +rethrow_rapi_rel_to_table <- function(rel, schema_name, table_name, temporary, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_set_alias(rel, alias), + rapi_rel_to_table(rel, schema_name, table_name, temporary), error = function(e) { rethrow_error_from_rapi(e, call) } ) } -rethrow_rapi_rel_sql <- function(rel, sql, call = parent.frame(2)) { +rethrow_rapi_rel_insert <- function(rel, schema_name, table_name, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_sql(rel, sql), + rapi_rel_insert(rel, schema_name, table_name), error = function(e) { rethrow_error_from_rapi(e, call) } ) } -rethrow_rapi_rel_names <- function(rel, call = parent.frame(2)) { +rethrow_rapi_rel_filter2 <- function(df, con, exprs, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_names(rel), + rapi_rel_filter2(df, con, exprs), error = function(e) { rethrow_error_from_rapi(e, call) } ) } -rethrow_rapi_rel_set_intersect <- function(rel_a, rel_b, call = parent.frame(2)) { +rethrow_rapi_rel_project2 <- function(df, con, exprs, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_set_intersect(rel_a, rel_b), + rapi_rel_project2(df, con, exprs), error = function(e) { rethrow_error_from_rapi(e, call) } ) } -rethrow_rapi_rel_set_diff <- function(rel_a, rel_b, call = parent.frame(2)) { +rethrow_rapi_rel_aggregate2 <- function(df, con, groups, aggregates, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_set_diff(rel_a, rel_b), + rapi_rel_aggregate2(df, con, groups, aggregates), error = function(e) { rethrow_error_from_rapi(e, call) } ) } -rethrow_rapi_rel_set_symdiff <- function(rel_a, rel_b, call = parent.frame(2)) { +rethrow_rapi_rel_order2 <- function(df, con, orders, ascending, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_set_symdiff(rel_a, rel_b), + rapi_rel_order2(df, con, orders, ascending), error = function(e) { rethrow_error_from_rapi(e, call) } ) } -rethrow_rapi_rel_from_sql <- function(con, sql, call = parent.frame(2)) { +rethrow_rapi_rel_join2 <- function(left, right, con, conds, join, join_ref_type, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_from_sql(con, sql), + rapi_rel_join2(left, right, con, conds, join, join_ref_type), error = function(e) { rethrow_error_from_rapi(e, call) } ) } -rethrow_rapi_rel_from_table <- function(con, schema_name, table_name, call = parent.frame(2)) { +rethrow_rapi_rel_union_all2 <- function(left, right, con, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_from_table(con, schema_name, table_name), + rapi_rel_union_all2(left, right, con), error = function(e) { rethrow_error_from_rapi(e, call) } ) } -rethrow_rapi_rel_from_table_function <- function(con, function_name, positional_parameters_sexps, named_parameters_sexps, call = parent.frame(2)) { +rethrow_rapi_rel_limit2 <- function(df, con, n, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_from_table_function(con, function_name, positional_parameters_sexps, named_parameters_sexps), + rapi_rel_limit2(df, con, n), error = function(e) { rethrow_error_from_rapi(e, call) } ) } -rethrow_rapi_rel_to_parquet <- function(rel, file_name, options_sexps, call = parent.frame(2)) { +rethrow_rapi_rel_distinct2 <- function(df, con, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_to_parquet(rel, file_name, options_sexps), + rapi_rel_distinct2(df, con), error = function(e) { rethrow_error_from_rapi(e, call) } ) } -rethrow_rapi_rel_to_csv <- function(rel, file_name, options_sexps, call = parent.frame(2)) { +rethrow_rapi_rel_names2 <- function(df, con, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_to_csv(rel, file_name, options_sexps), + rapi_rel_names2(df, con), error = function(e) { rethrow_error_from_rapi(e, call) } ) } -rethrow_rapi_rel_to_table <- function(rel, schema_name, table_name, temporary, call = parent.frame(2)) { +rethrow_rapi_rel_alias2 <- function(df, con, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_to_table(rel, schema_name, table_name, temporary), + rapi_rel_alias2(df, con), error = function(e) { rethrow_error_from_rapi(e, call) } ) } -rethrow_rapi_rel_insert <- function(rel, schema_name, table_name, call = parent.frame(2)) { +rethrow_rapi_rel_set_alias2 <- function(df, con, alias, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_insert(rel, schema_name, table_name), + rapi_rel_set_alias2(df, con, alias), error = function(e) { rethrow_error_from_rapi(e, call) } @@ -640,42 +676,46 @@ rethrow_restore <- function() { rethrow_rapi_expr_function <<- rapi_expr_function rethrow_rapi_expr_set_alias <<- rapi_expr_set_alias rethrow_rapi_expr_tostring <<- rapi_expr_tostring + rethrow_rapi_get_null_SEXP_ptr <<- rapi_get_null_SEXP_ptr rethrow_rapi_rel_from_df <<- rapi_rel_from_df + rethrow_rapi_rel_to_df <<- rapi_rel_to_df + rethrow_rapi_rel_sql <<- rapi_rel_sql + rethrow_rapi_rel_names <<- rapi_rel_names + rethrow_rapi_rel_alias <<- rapi_rel_alias + rethrow_rapi_rel_set_alias <<- rapi_rel_set_alias rethrow_rapi_rel_filter <<- rapi_rel_filter - rethrow_rapi_rel_filter2 <<- rapi_rel_filter2 rethrow_rapi_rel_project <<- rapi_rel_project - rethrow_rapi_rel_project2 <<- rapi_rel_project2 rethrow_rapi_rel_aggregate <<- rapi_rel_aggregate - rethrow_rapi_rel_aggregate2 <<- rapi_rel_aggregate2 rethrow_rapi_rel_order <<- rapi_rel_order - rethrow_rapi_rel_order2 <<- rapi_rel_order2 rethrow_rapi_expr_window <<- rapi_expr_window rethrow_rapi_rel_join <<- rapi_rel_join rethrow_rapi_rel_union_all <<- rapi_rel_union_all - rethrow_rapi_rel_union_all2 <<- rapi_rel_union_all2 rethrow_rapi_rel_limit <<- rapi_rel_limit - rethrow_rapi_rel_limit2 <<- rapi_rel_limit2 rethrow_rapi_rel_distinct <<- rapi_rel_distinct - rethrow_rapi_rel_distinct2 <<- rapi_rel_distinct2 - rethrow_rapi_rel_to_df <<- rapi_rel_to_df - rethrow_rapi_rel_tostring <<- rapi_rel_tostring - rethrow_rapi_rel_to_sql <<- rapi_rel_to_sql - rethrow_rapi_rel_explain <<- rapi_rel_explain - rethrow_rapi_rel_alias <<- rapi_rel_alias - rethrow_rapi_get_null_SEXP_ptr <<- rapi_get_null_SEXP_ptr - rethrow_rapi_rel_set_alias <<- rapi_rel_set_alias - rethrow_rapi_rel_sql <<- rapi_rel_sql - rethrow_rapi_rel_names <<- rapi_rel_names rethrow_rapi_rel_set_intersect <<- rapi_rel_set_intersect rethrow_rapi_rel_set_diff <<- rapi_rel_set_diff rethrow_rapi_rel_set_symdiff <<- rapi_rel_set_symdiff rethrow_rapi_rel_from_sql <<- rapi_rel_from_sql rethrow_rapi_rel_from_table <<- rapi_rel_from_table rethrow_rapi_rel_from_table_function <<- rapi_rel_from_table_function + rethrow_rapi_rel_tostring <<- rapi_rel_tostring + rethrow_rapi_rel_to_sql <<- rapi_rel_to_sql + rethrow_rapi_rel_explain <<- rapi_rel_explain rethrow_rapi_rel_to_parquet <<- rapi_rel_to_parquet rethrow_rapi_rel_to_csv <<- rapi_rel_to_csv rethrow_rapi_rel_to_table <<- rapi_rel_to_table rethrow_rapi_rel_insert <<- rapi_rel_insert + rethrow_rapi_rel_filter2 <<- rapi_rel_filter2 + rethrow_rapi_rel_project2 <<- rapi_rel_project2 + rethrow_rapi_rel_aggregate2 <<- rapi_rel_aggregate2 + rethrow_rapi_rel_order2 <<- rapi_rel_order2 + rethrow_rapi_rel_join2 <<- rapi_rel_join2 + rethrow_rapi_rel_union_all2 <<- rapi_rel_union_all2 + rethrow_rapi_rel_limit2 <<- rapi_rel_limit2 + rethrow_rapi_rel_distinct2 <<- rapi_rel_distinct2 + rethrow_rapi_rel_names2 <<- rapi_rel_names2 + rethrow_rapi_rel_alias2 <<- rapi_rel_alias2 + rethrow_rapi_rel_set_alias2 <<- rapi_rel_set_alias2 rethrow_rapi_rel_to_altrep <<- rapi_rel_to_altrep rethrow_rapi_rel_from_altrep_df <<- rapi_rel_from_altrep_df rethrow_rapi_release <<- rapi_release From ac94d7d30b802ae831b12d1d9d0b94e3854f4252 Mon Sep 17 00:00:00 2001 From: Antonov548 Date: Mon, 20 Jan 2025 17:20:40 +0100 Subject: [PATCH 39/69] add more methods --- R/cpp11.R | 12 ++++++++++++ R/relational.R | 39 +++++++++++++++++++++++++++++++++++++++ R/rethrow-gen.R | 30 ++++++++++++++++++++++++++++++ src/cpp11.cpp | 24 ++++++++++++++++++++++++ src/relational2.cpp | 39 ++++++++++++++++++++++++++++++++++++++- 5 files changed, 143 insertions(+), 1 deletion(-) diff --git a/R/cpp11.R b/R/cpp11.R index abb7dfad9..25383121c 100644 --- a/R/cpp11.R +++ b/R/cpp11.R @@ -220,6 +220,18 @@ rapi_rel_distinct2 <- function(df, con) { .Call(`_duckdb_rapi_rel_distinct2`, df, con) } +rapi_rel_set_intersect2 <- function(left, right, con) { + .Call(`_duckdb_rapi_rel_set_intersect2`, left, right, con) +} + +rapi_rel_set_diff2 <- function(left, right, con) { + .Call(`_duckdb_rapi_rel_set_diff2`, left, right, con) +} + +rapi_rel_set_symdiff2 <- function(left, right, con) { + .Call(`_duckdb_rapi_rel_set_symdiff2`, left, right, con) +} + rapi_rel_names2 <- function(df, con) { .Call(`_duckdb_rapi_rel_names2`, df, con) } diff --git a/R/relational.R b/R/relational.R index 2ad3eb77f..9d51f69f5 100644 --- a/R/relational.R +++ b/R/relational.R @@ -403,6 +403,19 @@ rel_set_intersect <- function(rel_a, rel_b) { rethrow_rapi_rel_set_intersect(rel_a, rel_b) } +#' SET INTERSECT on two DuckDB relation objects +#' @param rel_a a DuckDB relation object +#' @param rel_b a DuckDB relation object +#' @return a new `duckdb_relation` object resulting from the intersection +#' @noRd +#' @examples +#' rel_a <- rel_from_df(con, mtcars) +#' rel_b <- rel_from_df(con, mtcars) +#' rel_set_intersect_all(rel_a, rel_b) +rel_set_intersect2 <- function(df_a, df_b, con) { + rethrow_rapi_rel_set_intersect2(df_a, df_b, con@conn_ref) +} + #' SET DIFF on two DuckDB relation objects #' @param rel_a a DuckDB relation object #' @param rel_b a DuckDB relation object @@ -416,6 +429,19 @@ rel_set_diff <- function(rel_a, rel_b) { rethrow_rapi_rel_set_diff(rel_a, rel_b) } +#' SET DIFF on two DuckDB relation objects +#' @param rel_a a DuckDB relation object +#' @param rel_b a DuckDB relation object +#' @return a new `duckdb_relation` object resulting from the set difference +#' @noRd +#' @examples +#' rel_a <- rel_from_df(con, mtcars) +#' rel_b <- rel_from_df(con, mtcars) +#' rel_set_diff(rel_a, rel_b) +rel_set_diff2 <- function(df_a, df_b, con) { + rethrow_rapi_rel_set_diff2(df_a, df_b, con@conn_ref) +} + #' SET SYMDIFF on two DuckDB relation objects #' @param rel_a a DuckDB relation object #' @param rel_b a DuckDB relation object @@ -429,6 +455,19 @@ rel_set_symdiff <- function(rel_a, rel_b) { rethrow_rapi_rel_set_symdiff(rel_a, rel_b) } +#' SET SYMDIFF on two DuckDB relation objects +#' @param rel_a a DuckDB relation object +#' @param rel_b a DuckDB relation object +#' @return a new `duckdb_relation` object resulting from the symmetric difference of rel_a and rel_b +#' @noRd +#' @examples +#' rel_a <- rel_from_df(con, mtcars) +#' rel_b <- rel_from_df(con, mtcars) +#' rel_set_symdiff(rel_a, rel_b) +rel_set_symdiff2 <- function(df_a, df_b, con) { + rethrow_rapi_rel_set_symdiff2(df_a, df_b, con@conn_ref) +} + #' Run a SQL query on a DuckDB relation object #' @param rel the DuckDB relation object #' @param sql a SQL query to run, use `_` to refer back to the relation diff --git a/R/rethrow-gen.R b/R/rethrow-gen.R index aeee08c6c..81657612a 100644 --- a/R/rethrow-gen.R +++ b/R/rethrow-gen.R @@ -495,6 +495,33 @@ rethrow_rapi_rel_distinct2 <- function(df, con, call = parent.frame(2)) { ) } +rethrow_rapi_rel_set_intersect2 <- function(left, right, con, call = parent.frame(2)) { + rlang::try_fetch( + rapi_rel_set_intersect2(left, right, con), + error = function(e) { + rethrow_error_from_rapi(e, call) + } + ) +} + +rethrow_rapi_rel_set_diff2 <- function(left, right, con, call = parent.frame(2)) { + rlang::try_fetch( + rapi_rel_set_diff2(left, right, con), + error = function(e) { + rethrow_error_from_rapi(e, call) + } + ) +} + +rethrow_rapi_rel_set_symdiff2 <- function(left, right, con, call = parent.frame(2)) { + rlang::try_fetch( + rapi_rel_set_symdiff2(left, right, con), + error = function(e) { + rethrow_error_from_rapi(e, call) + } + ) +} + rethrow_rapi_rel_names2 <- function(df, con, call = parent.frame(2)) { rlang::try_fetch( rapi_rel_names2(df, con), @@ -713,6 +740,9 @@ rethrow_restore <- function() { rethrow_rapi_rel_union_all2 <<- rapi_rel_union_all2 rethrow_rapi_rel_limit2 <<- rapi_rel_limit2 rethrow_rapi_rel_distinct2 <<- rapi_rel_distinct2 + rethrow_rapi_rel_set_intersect2 <<- rapi_rel_set_intersect2 + rethrow_rapi_rel_set_diff2 <<- rapi_rel_set_diff2 + rethrow_rapi_rel_set_symdiff2 <<- rapi_rel_set_symdiff2 rethrow_rapi_rel_names2 <<- rapi_rel_names2 rethrow_rapi_rel_alias2 <<- rapi_rel_alias2 rethrow_rapi_rel_set_alias2 <<- rapi_rel_set_alias2 diff --git a/src/cpp11.cpp b/src/cpp11.cpp index 7a6de617d..c1e60c6c3 100644 --- a/src/cpp11.cpp +++ b/src/cpp11.cpp @@ -403,6 +403,27 @@ extern "C" SEXP _duckdb_rapi_rel_distinct2(SEXP df, SEXP con) { END_CPP11 } // relational2.cpp +SEXP rapi_rel_set_intersect2(data_frame left, data_frame right, duckdb::conn_eptr_t con); +extern "C" SEXP _duckdb_rapi_rel_set_intersect2(SEXP left, SEXP right, SEXP con) { + BEGIN_CPP11 + return cpp11::as_sexp(rapi_rel_set_intersect2(cpp11::as_cpp>(left), cpp11::as_cpp>(right), cpp11::as_cpp>(con))); + END_CPP11 +} +// relational2.cpp +SEXP rapi_rel_set_diff2(data_frame left, data_frame right, duckdb::conn_eptr_t con); +extern "C" SEXP _duckdb_rapi_rel_set_diff2(SEXP left, SEXP right, SEXP con) { + BEGIN_CPP11 + return cpp11::as_sexp(rapi_rel_set_diff2(cpp11::as_cpp>(left), cpp11::as_cpp>(right), cpp11::as_cpp>(con))); + END_CPP11 +} +// relational2.cpp +SEXP rapi_rel_set_symdiff2(data_frame left, data_frame right, duckdb::conn_eptr_t con); +extern "C" SEXP _duckdb_rapi_rel_set_symdiff2(SEXP left, SEXP right, SEXP con) { + BEGIN_CPP11 + return cpp11::as_sexp(rapi_rel_set_symdiff2(cpp11::as_cpp>(left), cpp11::as_cpp>(right), cpp11::as_cpp>(con))); + END_CPP11 +} +// relational2.cpp SEXP rapi_rel_names2(data_frame df, duckdb::conn_eptr_t con); extern "C" SEXP _duckdb_rapi_rel_names2(SEXP df, SEXP con) { BEGIN_CPP11 @@ -588,8 +609,11 @@ static const R_CallMethodDef CallEntries[] = { {"_duckdb_rapi_rel_set_alias", (DL_FUNC) &_duckdb_rapi_rel_set_alias, 2}, {"_duckdb_rapi_rel_set_alias2", (DL_FUNC) &_duckdb_rapi_rel_set_alias2, 3}, {"_duckdb_rapi_rel_set_diff", (DL_FUNC) &_duckdb_rapi_rel_set_diff, 2}, + {"_duckdb_rapi_rel_set_diff2", (DL_FUNC) &_duckdb_rapi_rel_set_diff2, 3}, {"_duckdb_rapi_rel_set_intersect", (DL_FUNC) &_duckdb_rapi_rel_set_intersect, 2}, + {"_duckdb_rapi_rel_set_intersect2", (DL_FUNC) &_duckdb_rapi_rel_set_intersect2, 3}, {"_duckdb_rapi_rel_set_symdiff", (DL_FUNC) &_duckdb_rapi_rel_set_symdiff, 2}, + {"_duckdb_rapi_rel_set_symdiff2", (DL_FUNC) &_duckdb_rapi_rel_set_symdiff2, 3}, {"_duckdb_rapi_rel_sql", (DL_FUNC) &_duckdb_rapi_rel_sql, 2}, {"_duckdb_rapi_rel_to_altrep", (DL_FUNC) &_duckdb_rapi_rel_to_altrep, 2}, {"_duckdb_rapi_rel_to_csv", (DL_FUNC) &_duckdb_rapi_rel_to_csv, 3}, diff --git a/src/relational2.cpp b/src/relational2.cpp index 6de0fe671..7e3f2e174 100644 --- a/src/relational2.cpp +++ b/src/relational2.cpp @@ -215,6 +215,43 @@ using namespace cpp11; return rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, make_shared_ptr(rel->rel)), con, true); } +[[cpp11::register]] SEXP rapi_rel_set_intersect2(data_frame left, data_frame right, duckdb::conn_eptr_t con) { + auto rel_left = cpp11::as_cpp>(rapi_rel_from_any_df(con, left, true)); + auto rel_right = cpp11::as_cpp>(rapi_rel_from_any_df(con, right, true)); + + auto res = make_shared_ptr(rel_left->rel, rel_right->rel, SetOperationType::INTERSECT); + + cpp11::writable::list prot = {rel_left, rel_right}; + + return rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, res), con, true); +} + +[[cpp11::register]] SEXP rapi_rel_set_diff2(data_frame left, data_frame right, duckdb::conn_eptr_t con) { + auto rel_left = cpp11::as_cpp>(rapi_rel_from_any_df(con, left, true)); + auto rel_right = cpp11::as_cpp>(rapi_rel_from_any_df(con, right, true)); + + auto res = make_shared_ptr(rel_left->rel, rel_right->rel, SetOperationType::EXCEPT); + + cpp11::writable::list prot = {rel_left, rel_right}; + + return rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, res), con, true); +} + +[[cpp11::register]] SEXP rapi_rel_set_symdiff2(data_frame left, data_frame right, duckdb::conn_eptr_t con) { + auto rel_left = cpp11::as_cpp>(rapi_rel_from_any_df(con, left, true)); + auto rel_right = cpp11::as_cpp>(rapi_rel_from_any_df(con, right, true)); + + // symdiff implemented using the equation below + // A symdiff B = (A except B) UNION (B except A) + auto a_except_b = make_shared_ptr(rel_left->rel, rel_right->rel, SetOperationType::EXCEPT); + auto b_except_a = make_shared_ptr(rel_right->rel, rel_left->rel, SetOperationType::EXCEPT); + auto symdiff = make_shared_ptr(a_except_b, b_except_a, SetOperationType::UNION); + + cpp11::writable::list prot = {rel_left, rel_right}; + + return rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, symdiff), con, true); +} + // DuckDB Relations: names [[cpp11::register]] SEXP rapi_rel_names2(data_frame df, duckdb::conn_eptr_t con) { @@ -236,5 +273,5 @@ using namespace cpp11; auto rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); cpp11::writable::list prot = {rel}; - return make_external_prot("duckdb_relation", prot, rel->rel->Alias(alias)); + return rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, rel->rel->Alias(alias)), con, true); } From 829e2b4a0e05fd989fb56a3966e5a76ee48a43b7 Mon Sep 17 00:00:00 2001 From: Antonov548 Date: Mon, 20 Jan 2025 17:22:36 +0100 Subject: [PATCH 40/69] fix: change relation to dataframe --- R/relational.R | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/R/relational.R b/R/relational.R index 9d51f69f5..b0cbca633 100644 --- a/R/relational.R +++ b/R/relational.R @@ -553,8 +553,8 @@ rel_set_alias <- function(rel, alias) { #' con <- DBI::dbConnect(duckdb()) #' rel <- rel_from_df(con, mtcars) #' rel_alias(rel) -rel_alias2 <- function(rel) { - rethrow_rapi_rel_alias2(rel) +rel_alias2 <- function(df, con) { + rethrow_rapi_rel_alias2(df, con@conn_ref) } #' Set the internal alias for a DuckDB relation object @@ -565,8 +565,8 @@ rel_alias2 <- function(rel) { #' con <- DBI::dbConnect(duckdb()) #' rel <- rel_from_df(con, mtcars) #' rel_set_alias(rel, "my_new_alias") -rel_set_alias2 <- function(rel, alias) { - rethrow_rapi_rel_set_alias2(rel, alias) +rel_set_alias2 <- function(df, con, alias) { + rethrow_rapi_rel_set_alias2(df, con@conn_ref, alias) } #' Transforms a relation object to a lazy data frame using altrep @@ -677,8 +677,8 @@ rel_names <- function(rel) { rethrow_rapi_rel_names(rel) } -rel_names2 <- function(rel) { - rethrow_rapi_rel_names2(rel) +rel_names2 <- function(df, con) { + rethrow_rapi_rel_names2(df, con@conn_ref) } load_rfuns <- function() { From 2426a16356ecce3f2902ad759f47ba6d561b8fd7 Mon Sep 17 00:00:00 2001 From: Antonov548 Date: Wed, 22 Jan 2025 11:42:29 +0100 Subject: [PATCH 41/69] change order --- src/relational2.cpp | 50 ++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/src/relational2.cpp b/src/relational2.cpp index 7e3f2e174..c2bbfe518 100644 --- a/src/relational2.cpp +++ b/src/relational2.cpp @@ -27,7 +27,31 @@ using namespace duckdb; using namespace cpp11; -// DuckDB Expressions +// DuckDB Relations: names + +[[cpp11::register]] SEXP rapi_rel_names2(data_frame df, duckdb::conn_eptr_t con) { + auto rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); + + auto ret = writable::strings(); + for (auto &col : rel->rel->Columns()) { + ret.push_back(col.Name()); + } + return (ret); +} + +[[cpp11::register]] std::string rapi_rel_alias2(data_frame df, duckdb::conn_eptr_t con) { + auto rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); + return rel->rel->GetAlias(); +} + +[[cpp11::register]] SEXP rapi_rel_set_alias2(data_frame df, duckdb::conn_eptr_t con, std::string alias) { + auto rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); + cpp11::writable::list prot = {rel}; + + return rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, rel->rel->Alias(alias)), con, true); +} + +// DuckDB Relations: operators [[cpp11::register]] SEXP rapi_rel_filter2(data_frame df, duckdb::conn_eptr_t con, list exprs) { duckdb::unique_ptr filter_expr; @@ -251,27 +275,3 @@ using namespace cpp11; return rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, symdiff), con, true); } - -// DuckDB Relations: names - -[[cpp11::register]] SEXP rapi_rel_names2(data_frame df, duckdb::conn_eptr_t con) { - auto rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); - - auto ret = writable::strings(); - for (auto &col : rel->rel->Columns()) { - ret.push_back(col.Name()); - } - return (ret); -} - -[[cpp11::register]] std::string rapi_rel_alias2(data_frame df, duckdb::conn_eptr_t con) { - auto rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); - return rel->rel->GetAlias(); -} - -[[cpp11::register]] SEXP rapi_rel_set_alias2(data_frame df, duckdb::conn_eptr_t con, std::string alias) { - auto rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); - cpp11::writable::list prot = {rel}; - - return rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, rel->rel->Alias(alias)), con, true); -} From 98d2310f6bce9d02b11445fd593e733be9ada65b Mon Sep 17 00:00:00 2001 From: Antonov548 Date: Wed, 22 Jan 2025 12:34:52 +0100 Subject: [PATCH 42/69] add conversion block --- R/cpp11.R | 44 ++++++- R/relational.R | 86 +++++++++++-- R/rethrow-gen.R | 98 +++++++++++++-- src/cpp11.cpp | 238 +++++++++++++++++++++++------------- src/include/reltoaltrep.hpp | 4 + src/relational.cpp | 26 ---- src/relational2.cpp | 89 +++++++++++++- src/reltoaltrep.cpp | 26 ++++ 8 files changed, 472 insertions(+), 139 deletions(-) diff --git a/R/cpp11.R b/R/cpp11.R index 25383121c..37c0a0f6b 100644 --- a/R/cpp11.R +++ b/R/cpp11.R @@ -188,6 +188,18 @@ rapi_rel_insert <- function(rel, schema_name, table_name) { invisible(.Call(`_duckdb_rapi_rel_insert`, rel, schema_name, table_name)) } +rapi_rel_names2 <- function(df, con) { + .Call(`_duckdb_rapi_rel_names2`, df, con) +} + +rapi_rel_alias2 <- function(df, con) { + .Call(`_duckdb_rapi_rel_alias2`, df, con) +} + +rapi_rel_set_alias2 <- function(df, con, alias) { + .Call(`_duckdb_rapi_rel_set_alias2`, df, con, alias) +} + rapi_rel_filter2 <- function(df, con, exprs) { .Call(`_duckdb_rapi_rel_filter2`, df, con, exprs) } @@ -232,16 +244,36 @@ rapi_rel_set_symdiff2 <- function(left, right, con) { .Call(`_duckdb_rapi_rel_set_symdiff2`, left, right, con) } -rapi_rel_names2 <- function(df, con) { - .Call(`_duckdb_rapi_rel_names2`, df, con) +rapi_rel_from_sql2 <- function(con, sql) { + .Call(`_duckdb_rapi_rel_from_sql2`, con, sql) } -rapi_rel_alias2 <- function(df, con) { - .Call(`_duckdb_rapi_rel_alias2`, df, con) +rapi_rel_from_table2 <- function(con, schema_name, table_name) { + .Call(`_duckdb_rapi_rel_from_table2`, con, schema_name, table_name) } -rapi_rel_set_alias2 <- function(df, con, alias) { - .Call(`_duckdb_rapi_rel_set_alias2`, df, con, alias) +rapi_rel_from_table_function2 <- function(con, function_name, positional_parameters_sexps, named_parameters_sexps) { + .Call(`_duckdb_rapi_rel_from_table_function2`, con, function_name, positional_parameters_sexps, named_parameters_sexps) +} + +rapi_rel_explain2 <- function(df, con, type, format) { + .Call(`_duckdb_rapi_rel_explain2`, df, con, type, format) +} + +rapi_rel_to_parquet2 <- function(df, con, file_name, options_sexps) { + invisible(.Call(`_duckdb_rapi_rel_to_parquet2`, df, con, file_name, options_sexps)) +} + +rapi_rel_to_csv2 <- function(df, con, file_name, options_sexps) { + invisible(.Call(`_duckdb_rapi_rel_to_csv2`, df, con, file_name, options_sexps)) +} + +rapi_rel_to_table2 <- function(df, con, schema_name, table_name, temporary) { + invisible(.Call(`_duckdb_rapi_rel_to_table2`, df, con, schema_name, table_name, temporary)) +} + +rapi_rel_insert2 <- function(df, con, schema_name, table_name) { + invisible(.Call(`_duckdb_rapi_rel_insert2`, df, con, schema_name, table_name)) } rapi_rel_to_altrep <- function(rel, allow_materialization) { diff --git a/R/relational.R b/R/relational.R index b0cbca633..f4409a71e 100644 --- a/R/relational.R +++ b/R/relational.R @@ -494,6 +494,19 @@ rel_explain <- function(rel) { invisible(NULL) } +#' Print the EXPLAIN output for a DuckDB relation object +#' @param rel the DuckDB relation object +#' @noRd +#' @examples +#' con <- DBI::dbConnect(duckdb()) +#' rel <- rel_from_df(con, mtcars) +#' rel_explain(rel) +rel_explain2 <- function(df, con) { + # Legacy + cat(rethrow_rapi_rel_explain2(df, con@conn_ref, "EXPLAIN_STANDARD", "DEFAULT")[[2]][[1]]) + invisible(NULL) +} + #' Return the EXPLAIN output for a DuckDB relation object as a data frame #' @param rel the DuckDB relation object #' @noRd @@ -534,27 +547,27 @@ rel_alias <- function(rel) { rethrow_rapi_rel_alias(rel) } -#' Set the internal alias for a DuckDB relation object +#' Get the internal alias for a DuckDB relation object #' @param rel the DuckDB relation object -#' @param alias the new alias #' @noRd #' @examples #' con <- DBI::dbConnect(duckdb()) #' rel <- rel_from_df(con, mtcars) -#' rel_set_alias(rel, "my_new_alias") -rel_set_alias <- function(rel, alias) { - rethrow_rapi_rel_set_alias(rel, alias) +#' rel_alias(rel) +rel_alias2 <- function(df, con) { + rethrow_rapi_rel_alias2(df, con@conn_ref) } -#' Get the internal alias for a DuckDB relation object +#' Set the internal alias for a DuckDB relation object #' @param rel the DuckDB relation object +#' @param alias the new alias #' @noRd #' @examples #' con <- DBI::dbConnect(duckdb()) #' rel <- rel_from_df(con, mtcars) -#' rel_alias(rel) -rel_alias2 <- function(df, con) { - rethrow_rapi_rel_alias2(df, con@conn_ref) +#' rel_set_alias(rel, "my_new_alias") +rel_set_alias <- function(rel, alias) { + rethrow_rapi_rel_set_alias(rel, alias) } #' Set the internal alias for a DuckDB relation object @@ -632,6 +645,18 @@ rel_from_sql <- function(con, sql) { rethrow_rapi_rel_from_sql(con@conn_ref, sql) } +#' Create a duckdb table relation from a table name +#' @param sql An SQL query +#' @return a duckdb relation +#' @noRd +#' @examples +#' con <- DBI::dbConnect(duckdb()) +#' DBI::dbWriteTable(con, "mtcars", mtcars) +#' rel <- rel_from_sql(con, "SELECT * FROM mtcars") +rel_from_sql2 <- function(con, sql) { + rethrow_rapi_rel_from_sql2(con@conn_ref, sql) +} + #' Create a duckdb table relation from a table name #' @param table the table name #' @return a duckdb relation @@ -644,6 +669,18 @@ rel_from_table <- function(con, table_name, schema_name = "MAIN") { rethrow_rapi_rel_from_table(con@conn_ref, schema_name, table_name) } +#' Create a duckdb table relation from a table name +#' @param table the table name +#' @return a duckdb relation +#' @noRd +#' @examples +#' con <- DBI::dbConnect(duckdb()) +#' DBI::dbWriteTable(con, "mtcars", mtcars) +#' rel <- rel_from_table(con, "mtcars") +rel_from_table2 <- function(con, table_name, schema_name = "MAIN") { + rethrow_rapi_rel_from_table2(con@conn_ref, schema_name, table_name) +} + #' Convert a duckdb relation from a table-producing function #' @param name the table function name #' @param positional_parameters the table function positional parameters list @@ -657,22 +694,51 @@ rel_from_table_function <- function(con, function_name, positional_parameters = rethrow_rapi_rel_from_table_function(con@conn_ref, function_name, positional_parameters, named_parameters) } +#' Convert a duckdb relation from a table-producing function +#' @param name the table function name +#' @param positional_parameters the table function positional parameters list +#' @param named_parameters the table function named parameters list +#' @return a duckdb relation +#' @noRd +#' @examples +#' con <- DBI::dbConnect(duckdb()) +#' rel <- rel_from_table_function(con, 'generate_series', list(10L)) +rel_from_table_function2 <- function(con, function_name, positional_parameters = list(), named_parameters = list()) { + rethrow_rapi_rel_from_table_function2(con@conn_ref, function_name, positional_parameters, named_parameters) +} + rel_to_parquet <- function(rel, file_name, options = list()) { rethrow_rapi_rel_to_parquet(rel, file_name, options) } +rel_to_parquet2 <- function(df, con, file_name, options = list()) { + rethrow_rapi_rel_to_parquet2(df, con@conn_ref, file_name, options) +} + rel_to_csv <- function(rel, file_name, options = list()) { rethrow_rapi_rel_to_csv(rel, file_name, options) } +rel_to_csv2 <- function(df, con, file_name, options = list()) { + rethrow_rapi_rel_to_csv2(df, con@conn_ref, file_name, options) +} + rel_to_table <- function(rel, schema_name, table_name, temporary) { - rethrow_rapi_rel_to_table(rel, schema_name, table_name, temporary) + rethrow_rapi_rel_to_table2(rel, schema_name, table_name, temporary) +} + +rel_to_table2 <- function(df, con, schema_name, table_name, temporary) { + rethrow_rapi_rel_to_table2(df, con@conn_ref, schema_name, table_name, temporary) } rel_insert <- function(rel, schema_name, table_name) { rethrow_rapi_rel_insert(rel, schema_name, table_name) } +rel_insert2 <- function(df, con, schema_name, table_name) { + rethrow_rapi_rel_insert2(df, con@conn_ref, schema_name, table_name) +} + rel_names <- function(rel) { rethrow_rapi_rel_names(rel) } diff --git a/R/rethrow-gen.R b/R/rethrow-gen.R index 81657612a..7e007b72c 100644 --- a/R/rethrow-gen.R +++ b/R/rethrow-gen.R @@ -423,6 +423,33 @@ rethrow_rapi_rel_insert <- function(rel, schema_name, table_name, call = parent. ) } +rethrow_rapi_rel_names2 <- function(df, con, call = parent.frame(2)) { + rlang::try_fetch( + rapi_rel_names2(df, con), + error = function(e) { + rethrow_error_from_rapi(e, call) + } + ) +} + +rethrow_rapi_rel_alias2 <- function(df, con, call = parent.frame(2)) { + rlang::try_fetch( + rapi_rel_alias2(df, con), + error = function(e) { + rethrow_error_from_rapi(e, call) + } + ) +} + +rethrow_rapi_rel_set_alias2 <- function(df, con, alias, call = parent.frame(2)) { + rlang::try_fetch( + rapi_rel_set_alias2(df, con, alias), + error = function(e) { + rethrow_error_from_rapi(e, call) + } + ) +} + rethrow_rapi_rel_filter2 <- function(df, con, exprs, call = parent.frame(2)) { rlang::try_fetch( rapi_rel_filter2(df, con, exprs), @@ -522,27 +549,72 @@ rethrow_rapi_rel_set_symdiff2 <- function(left, right, con, call = parent.frame( ) } -rethrow_rapi_rel_names2 <- function(df, con, call = parent.frame(2)) { +rethrow_rapi_rel_from_sql2 <- function(con, sql, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_names2(df, con), + rapi_rel_from_sql2(con, sql), error = function(e) { rethrow_error_from_rapi(e, call) } ) } -rethrow_rapi_rel_alias2 <- function(df, con, call = parent.frame(2)) { +rethrow_rapi_rel_from_table2 <- function(con, schema_name, table_name, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_alias2(df, con), + rapi_rel_from_table2(con, schema_name, table_name), error = function(e) { rethrow_error_from_rapi(e, call) } ) } -rethrow_rapi_rel_set_alias2 <- function(df, con, alias, call = parent.frame(2)) { +rethrow_rapi_rel_from_table_function2 <- function(con, function_name, positional_parameters_sexps, named_parameters_sexps, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_set_alias2(df, con, alias), + rapi_rel_from_table_function2(con, function_name, positional_parameters_sexps, named_parameters_sexps), + error = function(e) { + rethrow_error_from_rapi(e, call) + } + ) +} + +rethrow_rapi_rel_explain2 <- function(df, con, type, format, call = parent.frame(2)) { + rlang::try_fetch( + rapi_rel_explain2(df, con, type, format), + error = function(e) { + rethrow_error_from_rapi(e, call) + } + ) +} + +rethrow_rapi_rel_to_parquet2 <- function(df, con, file_name, options_sexps, call = parent.frame(2)) { + rlang::try_fetch( + rapi_rel_to_parquet2(df, con, file_name, options_sexps), + error = function(e) { + rethrow_error_from_rapi(e, call) + } + ) +} + +rethrow_rapi_rel_to_csv2 <- function(df, con, file_name, options_sexps, call = parent.frame(2)) { + rlang::try_fetch( + rapi_rel_to_csv2(df, con, file_name, options_sexps), + error = function(e) { + rethrow_error_from_rapi(e, call) + } + ) +} + +rethrow_rapi_rel_to_table2 <- function(df, con, schema_name, table_name, temporary, call = parent.frame(2)) { + rlang::try_fetch( + rapi_rel_to_table2(df, con, schema_name, table_name, temporary), + error = function(e) { + rethrow_error_from_rapi(e, call) + } + ) +} + +rethrow_rapi_rel_insert2 <- function(df, con, schema_name, table_name, call = parent.frame(2)) { + rlang::try_fetch( + rapi_rel_insert2(df, con, schema_name, table_name), error = function(e) { rethrow_error_from_rapi(e, call) } @@ -732,6 +804,9 @@ rethrow_restore <- function() { rethrow_rapi_rel_to_csv <<- rapi_rel_to_csv rethrow_rapi_rel_to_table <<- rapi_rel_to_table rethrow_rapi_rel_insert <<- rapi_rel_insert + rethrow_rapi_rel_names2 <<- rapi_rel_names2 + rethrow_rapi_rel_alias2 <<- rapi_rel_alias2 + rethrow_rapi_rel_set_alias2 <<- rapi_rel_set_alias2 rethrow_rapi_rel_filter2 <<- rapi_rel_filter2 rethrow_rapi_rel_project2 <<- rapi_rel_project2 rethrow_rapi_rel_aggregate2 <<- rapi_rel_aggregate2 @@ -743,9 +818,14 @@ rethrow_restore <- function() { rethrow_rapi_rel_set_intersect2 <<- rapi_rel_set_intersect2 rethrow_rapi_rel_set_diff2 <<- rapi_rel_set_diff2 rethrow_rapi_rel_set_symdiff2 <<- rapi_rel_set_symdiff2 - rethrow_rapi_rel_names2 <<- rapi_rel_names2 - rethrow_rapi_rel_alias2 <<- rapi_rel_alias2 - rethrow_rapi_rel_set_alias2 <<- rapi_rel_set_alias2 + rethrow_rapi_rel_from_sql2 <<- rapi_rel_from_sql2 + rethrow_rapi_rel_from_table2 <<- rapi_rel_from_table2 + rethrow_rapi_rel_from_table_function2 <<- rapi_rel_from_table_function2 + rethrow_rapi_rel_explain2 <<- rapi_rel_explain2 + rethrow_rapi_rel_to_parquet2 <<- rapi_rel_to_parquet2 + rethrow_rapi_rel_to_csv2 <<- rapi_rel_to_csv2 + rethrow_rapi_rel_to_table2 <<- rapi_rel_to_table2 + rethrow_rapi_rel_insert2 <<- rapi_rel_insert2 rethrow_rapi_rel_to_altrep <<- rapi_rel_to_altrep rethrow_rapi_rel_from_altrep_df <<- rapi_rel_from_altrep_df rethrow_rapi_release <<- rapi_release diff --git a/src/cpp11.cpp b/src/cpp11.cpp index c1e60c6c3..60839cff7 100644 --- a/src/cpp11.cpp +++ b/src/cpp11.cpp @@ -347,6 +347,27 @@ extern "C" SEXP _duckdb_rapi_rel_insert(SEXP rel, SEXP schema_name, SEXP table_n END_CPP11 } // relational2.cpp +SEXP rapi_rel_names2(data_frame df, duckdb::conn_eptr_t con); +extern "C" SEXP _duckdb_rapi_rel_names2(SEXP df, SEXP con) { + BEGIN_CPP11 + return cpp11::as_sexp(rapi_rel_names2(cpp11::as_cpp>(df), cpp11::as_cpp>(con))); + END_CPP11 +} +// relational2.cpp +std::string rapi_rel_alias2(data_frame df, duckdb::conn_eptr_t con); +extern "C" SEXP _duckdb_rapi_rel_alias2(SEXP df, SEXP con) { + BEGIN_CPP11 + return cpp11::as_sexp(rapi_rel_alias2(cpp11::as_cpp>(df), cpp11::as_cpp>(con))); + END_CPP11 +} +// relational2.cpp +SEXP rapi_rel_set_alias2(data_frame df, duckdb::conn_eptr_t con, std::string alias); +extern "C" SEXP _duckdb_rapi_rel_set_alias2(SEXP df, SEXP con, SEXP alias) { + BEGIN_CPP11 + return cpp11::as_sexp(rapi_rel_set_alias2(cpp11::as_cpp>(df), cpp11::as_cpp>(con), cpp11::as_cpp>(alias))); + END_CPP11 +} +// relational2.cpp SEXP rapi_rel_filter2(data_frame df, duckdb::conn_eptr_t con, list exprs); extern "C" SEXP _duckdb_rapi_rel_filter2(SEXP df, SEXP con, SEXP exprs) { BEGIN_CPP11 @@ -424,24 +445,63 @@ extern "C" SEXP _duckdb_rapi_rel_set_symdiff2(SEXP left, SEXP right, SEXP con) { END_CPP11 } // relational2.cpp -SEXP rapi_rel_names2(data_frame df, duckdb::conn_eptr_t con); -extern "C" SEXP _duckdb_rapi_rel_names2(SEXP df, SEXP con) { +SEXP rapi_rel_from_sql2(duckdb::conn_eptr_t con, const std::string sql); +extern "C" SEXP _duckdb_rapi_rel_from_sql2(SEXP con, SEXP sql) { BEGIN_CPP11 - return cpp11::as_sexp(rapi_rel_names2(cpp11::as_cpp>(df), cpp11::as_cpp>(con))); + return cpp11::as_sexp(rapi_rel_from_sql2(cpp11::as_cpp>(con), cpp11::as_cpp>(sql))); END_CPP11 } // relational2.cpp -std::string rapi_rel_alias2(data_frame df, duckdb::conn_eptr_t con); -extern "C" SEXP _duckdb_rapi_rel_alias2(SEXP df, SEXP con) { +SEXP rapi_rel_from_table2(duckdb::conn_eptr_t con, const std::string schema_name, const std::string table_name); +extern "C" SEXP _duckdb_rapi_rel_from_table2(SEXP con, SEXP schema_name, SEXP table_name) { BEGIN_CPP11 - return cpp11::as_sexp(rapi_rel_alias2(cpp11::as_cpp>(df), cpp11::as_cpp>(con))); + return cpp11::as_sexp(rapi_rel_from_table2(cpp11::as_cpp>(con), cpp11::as_cpp>(schema_name), cpp11::as_cpp>(table_name))); END_CPP11 } // relational2.cpp -SEXP rapi_rel_set_alias2(data_frame df, duckdb::conn_eptr_t con, std::string alias); -extern "C" SEXP _duckdb_rapi_rel_set_alias2(SEXP df, SEXP con, SEXP alias) { +SEXP rapi_rel_from_table_function2(duckdb::conn_eptr_t con, const std::string function_name, list positional_parameters_sexps, list named_parameters_sexps); +extern "C" SEXP _duckdb_rapi_rel_from_table_function2(SEXP con, SEXP function_name, SEXP positional_parameters_sexps, SEXP named_parameters_sexps) { BEGIN_CPP11 - return cpp11::as_sexp(rapi_rel_set_alias2(cpp11::as_cpp>(df), cpp11::as_cpp>(con), cpp11::as_cpp>(alias))); + return cpp11::as_sexp(rapi_rel_from_table_function2(cpp11::as_cpp>(con), cpp11::as_cpp>(function_name), cpp11::as_cpp>(positional_parameters_sexps), cpp11::as_cpp>(named_parameters_sexps))); + END_CPP11 +} +// relational2.cpp +SEXP rapi_rel_explain2(data_frame df, duckdb::conn_eptr_t con, std::string type, std::string format); +extern "C" SEXP _duckdb_rapi_rel_explain2(SEXP df, SEXP con, SEXP type, SEXP format) { + BEGIN_CPP11 + return cpp11::as_sexp(rapi_rel_explain2(cpp11::as_cpp>(df), cpp11::as_cpp>(con), cpp11::as_cpp>(type), cpp11::as_cpp>(format))); + END_CPP11 +} +// relational2.cpp +void rapi_rel_to_parquet2(data_frame df, duckdb::conn_eptr_t con, std::string file_name, list options_sexps); +extern "C" SEXP _duckdb_rapi_rel_to_parquet2(SEXP df, SEXP con, SEXP file_name, SEXP options_sexps) { + BEGIN_CPP11 + rapi_rel_to_parquet2(cpp11::as_cpp>(df), cpp11::as_cpp>(con), cpp11::as_cpp>(file_name), cpp11::as_cpp>(options_sexps)); + return R_NilValue; + END_CPP11 +} +// relational2.cpp +void rapi_rel_to_csv2(data_frame df, duckdb::conn_eptr_t con, std::string file_name, list options_sexps); +extern "C" SEXP _duckdb_rapi_rel_to_csv2(SEXP df, SEXP con, SEXP file_name, SEXP options_sexps) { + BEGIN_CPP11 + rapi_rel_to_csv2(cpp11::as_cpp>(df), cpp11::as_cpp>(con), cpp11::as_cpp>(file_name), cpp11::as_cpp>(options_sexps)); + return R_NilValue; + END_CPP11 +} +// relational2.cpp +void rapi_rel_to_table2(data_frame df, duckdb::conn_eptr_t con, std::string schema_name, std::string table_name, bool temporary); +extern "C" SEXP _duckdb_rapi_rel_to_table2(SEXP df, SEXP con, SEXP schema_name, SEXP table_name, SEXP temporary) { + BEGIN_CPP11 + rapi_rel_to_table2(cpp11::as_cpp>(df), cpp11::as_cpp>(con), cpp11::as_cpp>(schema_name), cpp11::as_cpp>(table_name), cpp11::as_cpp>(temporary)); + return R_NilValue; + END_CPP11 +} +// relational2.cpp +void rapi_rel_insert2(data_frame df, duckdb::conn_eptr_t con, std::string schema_name, std::string table_name); +extern "C" SEXP _duckdb_rapi_rel_insert2(SEXP df, SEXP con, SEXP schema_name, SEXP table_name) { + BEGIN_CPP11 + rapi_rel_insert2(cpp11::as_cpp>(df), cpp11::as_cpp>(con), cpp11::as_cpp>(schema_name), cpp11::as_cpp>(table_name)); + return R_NilValue; END_CPP11 } // reltoaltrep.cpp @@ -554,82 +614,90 @@ extern "C" SEXP _duckdb_rapi_load_rfuns(SEXP dual) { extern "C" { static const R_CallMethodDef CallEntries[] = { - {"_duckdb_rapi_adbc_init_func", (DL_FUNC) &_duckdb_rapi_adbc_init_func, 0}, - {"_duckdb_rapi_bind", (DL_FUNC) &_duckdb_rapi_bind, 4}, - {"_duckdb_rapi_connect", (DL_FUNC) &_duckdb_rapi_connect, 1}, - {"_duckdb_rapi_disconnect", (DL_FUNC) &_duckdb_rapi_disconnect, 1}, - {"_duckdb_rapi_execute", (DL_FUNC) &_duckdb_rapi_execute, 3}, - {"_duckdb_rapi_execute_arrow", (DL_FUNC) &_duckdb_rapi_execute_arrow, 2}, - {"_duckdb_rapi_expr_comparison", (DL_FUNC) &_duckdb_rapi_expr_comparison, 2}, - {"_duckdb_rapi_expr_constant", (DL_FUNC) &_duckdb_rapi_expr_constant, 1}, - {"_duckdb_rapi_expr_function", (DL_FUNC) &_duckdb_rapi_expr_function, 4}, - {"_duckdb_rapi_expr_reference", (DL_FUNC) &_duckdb_rapi_expr_reference, 1}, - {"_duckdb_rapi_expr_set_alias", (DL_FUNC) &_duckdb_rapi_expr_set_alias, 2}, - {"_duckdb_rapi_expr_tostring", (DL_FUNC) &_duckdb_rapi_expr_tostring, 1}, - {"_duckdb_rapi_expr_window", (DL_FUNC) &_duckdb_rapi_expr_window, 9}, - {"_duckdb_rapi_get_null_SEXP_ptr", (DL_FUNC) &_duckdb_rapi_get_null_SEXP_ptr, 0}, - {"_duckdb_rapi_get_substrait", (DL_FUNC) &_duckdb_rapi_get_substrait, 3}, - {"_duckdb_rapi_get_substrait_json", (DL_FUNC) &_duckdb_rapi_get_substrait_json, 3}, - {"_duckdb_rapi_is_locked", (DL_FUNC) &_duckdb_rapi_is_locked, 1}, - {"_duckdb_rapi_list_arrow", (DL_FUNC) &_duckdb_rapi_list_arrow, 1}, - {"_duckdb_rapi_load_rfuns", (DL_FUNC) &_duckdb_rapi_load_rfuns, 1}, - {"_duckdb_rapi_lock", (DL_FUNC) &_duckdb_rapi_lock, 1}, - {"_duckdb_rapi_prepare", (DL_FUNC) &_duckdb_rapi_prepare, 3}, - {"_duckdb_rapi_prepare_substrait", (DL_FUNC) &_duckdb_rapi_prepare_substrait, 2}, - {"_duckdb_rapi_prepare_substrait_json", (DL_FUNC) &_duckdb_rapi_prepare_substrait_json, 2}, - {"_duckdb_rapi_ptr_to_str", (DL_FUNC) &_duckdb_rapi_ptr_to_str, 1}, - {"_duckdb_rapi_record_batch", (DL_FUNC) &_duckdb_rapi_record_batch, 2}, - {"_duckdb_rapi_register_arrow", (DL_FUNC) &_duckdb_rapi_register_arrow, 4}, - {"_duckdb_rapi_register_df", (DL_FUNC) &_duckdb_rapi_register_df, 6}, - {"_duckdb_rapi_rel_aggregate", (DL_FUNC) &_duckdb_rapi_rel_aggregate, 3}, - {"_duckdb_rapi_rel_aggregate2", (DL_FUNC) &_duckdb_rapi_rel_aggregate2, 4}, - {"_duckdb_rapi_rel_alias", (DL_FUNC) &_duckdb_rapi_rel_alias, 1}, - {"_duckdb_rapi_rel_alias2", (DL_FUNC) &_duckdb_rapi_rel_alias2, 2}, - {"_duckdb_rapi_rel_distinct", (DL_FUNC) &_duckdb_rapi_rel_distinct, 1}, - {"_duckdb_rapi_rel_distinct2", (DL_FUNC) &_duckdb_rapi_rel_distinct2, 2}, - {"_duckdb_rapi_rel_explain", (DL_FUNC) &_duckdb_rapi_rel_explain, 3}, - {"_duckdb_rapi_rel_filter", (DL_FUNC) &_duckdb_rapi_rel_filter, 2}, - {"_duckdb_rapi_rel_filter2", (DL_FUNC) &_duckdb_rapi_rel_filter2, 3}, - {"_duckdb_rapi_rel_from_altrep_df", (DL_FUNC) &_duckdb_rapi_rel_from_altrep_df, 3}, - {"_duckdb_rapi_rel_from_df", (DL_FUNC) &_duckdb_rapi_rel_from_df, 3}, - {"_duckdb_rapi_rel_from_sql", (DL_FUNC) &_duckdb_rapi_rel_from_sql, 2}, - {"_duckdb_rapi_rel_from_table", (DL_FUNC) &_duckdb_rapi_rel_from_table, 3}, - {"_duckdb_rapi_rel_from_table_function", (DL_FUNC) &_duckdb_rapi_rel_from_table_function, 4}, - {"_duckdb_rapi_rel_insert", (DL_FUNC) &_duckdb_rapi_rel_insert, 3}, - {"_duckdb_rapi_rel_join", (DL_FUNC) &_duckdb_rapi_rel_join, 5}, - {"_duckdb_rapi_rel_join2", (DL_FUNC) &_duckdb_rapi_rel_join2, 6}, - {"_duckdb_rapi_rel_limit", (DL_FUNC) &_duckdb_rapi_rel_limit, 2}, - {"_duckdb_rapi_rel_limit2", (DL_FUNC) &_duckdb_rapi_rel_limit2, 3}, - {"_duckdb_rapi_rel_names", (DL_FUNC) &_duckdb_rapi_rel_names, 1}, - {"_duckdb_rapi_rel_names2", (DL_FUNC) &_duckdb_rapi_rel_names2, 2}, - {"_duckdb_rapi_rel_order", (DL_FUNC) &_duckdb_rapi_rel_order, 3}, - {"_duckdb_rapi_rel_order2", (DL_FUNC) &_duckdb_rapi_rel_order2, 4}, - {"_duckdb_rapi_rel_project", (DL_FUNC) &_duckdb_rapi_rel_project, 2}, - {"_duckdb_rapi_rel_project2", (DL_FUNC) &_duckdb_rapi_rel_project2, 3}, - {"_duckdb_rapi_rel_set_alias", (DL_FUNC) &_duckdb_rapi_rel_set_alias, 2}, - {"_duckdb_rapi_rel_set_alias2", (DL_FUNC) &_duckdb_rapi_rel_set_alias2, 3}, - {"_duckdb_rapi_rel_set_diff", (DL_FUNC) &_duckdb_rapi_rel_set_diff, 2}, - {"_duckdb_rapi_rel_set_diff2", (DL_FUNC) &_duckdb_rapi_rel_set_diff2, 3}, - {"_duckdb_rapi_rel_set_intersect", (DL_FUNC) &_duckdb_rapi_rel_set_intersect, 2}, - {"_duckdb_rapi_rel_set_intersect2", (DL_FUNC) &_duckdb_rapi_rel_set_intersect2, 3}, - {"_duckdb_rapi_rel_set_symdiff", (DL_FUNC) &_duckdb_rapi_rel_set_symdiff, 2}, - {"_duckdb_rapi_rel_set_symdiff2", (DL_FUNC) &_duckdb_rapi_rel_set_symdiff2, 3}, - {"_duckdb_rapi_rel_sql", (DL_FUNC) &_duckdb_rapi_rel_sql, 2}, - {"_duckdb_rapi_rel_to_altrep", (DL_FUNC) &_duckdb_rapi_rel_to_altrep, 2}, - {"_duckdb_rapi_rel_to_csv", (DL_FUNC) &_duckdb_rapi_rel_to_csv, 3}, - {"_duckdb_rapi_rel_to_df", (DL_FUNC) &_duckdb_rapi_rel_to_df, 1}, - {"_duckdb_rapi_rel_to_parquet", (DL_FUNC) &_duckdb_rapi_rel_to_parquet, 3}, - {"_duckdb_rapi_rel_to_sql", (DL_FUNC) &_duckdb_rapi_rel_to_sql, 1}, - {"_duckdb_rapi_rel_to_table", (DL_FUNC) &_duckdb_rapi_rel_to_table, 4}, - {"_duckdb_rapi_rel_tostring", (DL_FUNC) &_duckdb_rapi_rel_tostring, 2}, - {"_duckdb_rapi_rel_union_all", (DL_FUNC) &_duckdb_rapi_rel_union_all, 2}, - {"_duckdb_rapi_rel_union_all2", (DL_FUNC) &_duckdb_rapi_rel_union_all2, 3}, - {"_duckdb_rapi_release", (DL_FUNC) &_duckdb_rapi_release, 1}, - {"_duckdb_rapi_shutdown", (DL_FUNC) &_duckdb_rapi_shutdown, 1}, - {"_duckdb_rapi_startup", (DL_FUNC) &_duckdb_rapi_startup, 4}, - {"_duckdb_rapi_unlock", (DL_FUNC) &_duckdb_rapi_unlock, 1}, - {"_duckdb_rapi_unregister_arrow", (DL_FUNC) &_duckdb_rapi_unregister_arrow, 2}, - {"_duckdb_rapi_unregister_df", (DL_FUNC) &_duckdb_rapi_unregister_df, 2}, + {"_duckdb_rapi_adbc_init_func", (DL_FUNC) &_duckdb_rapi_adbc_init_func, 0}, + {"_duckdb_rapi_bind", (DL_FUNC) &_duckdb_rapi_bind, 4}, + {"_duckdb_rapi_connect", (DL_FUNC) &_duckdb_rapi_connect, 1}, + {"_duckdb_rapi_disconnect", (DL_FUNC) &_duckdb_rapi_disconnect, 1}, + {"_duckdb_rapi_execute", (DL_FUNC) &_duckdb_rapi_execute, 3}, + {"_duckdb_rapi_execute_arrow", (DL_FUNC) &_duckdb_rapi_execute_arrow, 2}, + {"_duckdb_rapi_expr_comparison", (DL_FUNC) &_duckdb_rapi_expr_comparison, 2}, + {"_duckdb_rapi_expr_constant", (DL_FUNC) &_duckdb_rapi_expr_constant, 1}, + {"_duckdb_rapi_expr_function", (DL_FUNC) &_duckdb_rapi_expr_function, 4}, + {"_duckdb_rapi_expr_reference", (DL_FUNC) &_duckdb_rapi_expr_reference, 1}, + {"_duckdb_rapi_expr_set_alias", (DL_FUNC) &_duckdb_rapi_expr_set_alias, 2}, + {"_duckdb_rapi_expr_tostring", (DL_FUNC) &_duckdb_rapi_expr_tostring, 1}, + {"_duckdb_rapi_expr_window", (DL_FUNC) &_duckdb_rapi_expr_window, 9}, + {"_duckdb_rapi_get_null_SEXP_ptr", (DL_FUNC) &_duckdb_rapi_get_null_SEXP_ptr, 0}, + {"_duckdb_rapi_get_substrait", (DL_FUNC) &_duckdb_rapi_get_substrait, 3}, + {"_duckdb_rapi_get_substrait_json", (DL_FUNC) &_duckdb_rapi_get_substrait_json, 3}, + {"_duckdb_rapi_is_locked", (DL_FUNC) &_duckdb_rapi_is_locked, 1}, + {"_duckdb_rapi_list_arrow", (DL_FUNC) &_duckdb_rapi_list_arrow, 1}, + {"_duckdb_rapi_load_rfuns", (DL_FUNC) &_duckdb_rapi_load_rfuns, 1}, + {"_duckdb_rapi_lock", (DL_FUNC) &_duckdb_rapi_lock, 1}, + {"_duckdb_rapi_prepare", (DL_FUNC) &_duckdb_rapi_prepare, 3}, + {"_duckdb_rapi_prepare_substrait", (DL_FUNC) &_duckdb_rapi_prepare_substrait, 2}, + {"_duckdb_rapi_prepare_substrait_json", (DL_FUNC) &_duckdb_rapi_prepare_substrait_json, 2}, + {"_duckdb_rapi_ptr_to_str", (DL_FUNC) &_duckdb_rapi_ptr_to_str, 1}, + {"_duckdb_rapi_record_batch", (DL_FUNC) &_duckdb_rapi_record_batch, 2}, + {"_duckdb_rapi_register_arrow", (DL_FUNC) &_duckdb_rapi_register_arrow, 4}, + {"_duckdb_rapi_register_df", (DL_FUNC) &_duckdb_rapi_register_df, 6}, + {"_duckdb_rapi_rel_aggregate", (DL_FUNC) &_duckdb_rapi_rel_aggregate, 3}, + {"_duckdb_rapi_rel_aggregate2", (DL_FUNC) &_duckdb_rapi_rel_aggregate2, 4}, + {"_duckdb_rapi_rel_alias", (DL_FUNC) &_duckdb_rapi_rel_alias, 1}, + {"_duckdb_rapi_rel_alias2", (DL_FUNC) &_duckdb_rapi_rel_alias2, 2}, + {"_duckdb_rapi_rel_distinct", (DL_FUNC) &_duckdb_rapi_rel_distinct, 1}, + {"_duckdb_rapi_rel_distinct2", (DL_FUNC) &_duckdb_rapi_rel_distinct2, 2}, + {"_duckdb_rapi_rel_explain", (DL_FUNC) &_duckdb_rapi_rel_explain, 3}, + {"_duckdb_rapi_rel_explain2", (DL_FUNC) &_duckdb_rapi_rel_explain2, 4}, + {"_duckdb_rapi_rel_filter", (DL_FUNC) &_duckdb_rapi_rel_filter, 2}, + {"_duckdb_rapi_rel_filter2", (DL_FUNC) &_duckdb_rapi_rel_filter2, 3}, + {"_duckdb_rapi_rel_from_altrep_df", (DL_FUNC) &_duckdb_rapi_rel_from_altrep_df, 3}, + {"_duckdb_rapi_rel_from_df", (DL_FUNC) &_duckdb_rapi_rel_from_df, 3}, + {"_duckdb_rapi_rel_from_sql", (DL_FUNC) &_duckdb_rapi_rel_from_sql, 2}, + {"_duckdb_rapi_rel_from_sql2", (DL_FUNC) &_duckdb_rapi_rel_from_sql2, 2}, + {"_duckdb_rapi_rel_from_table", (DL_FUNC) &_duckdb_rapi_rel_from_table, 3}, + {"_duckdb_rapi_rel_from_table2", (DL_FUNC) &_duckdb_rapi_rel_from_table2, 3}, + {"_duckdb_rapi_rel_from_table_function", (DL_FUNC) &_duckdb_rapi_rel_from_table_function, 4}, + {"_duckdb_rapi_rel_from_table_function2", (DL_FUNC) &_duckdb_rapi_rel_from_table_function2, 4}, + {"_duckdb_rapi_rel_insert", (DL_FUNC) &_duckdb_rapi_rel_insert, 3}, + {"_duckdb_rapi_rel_insert2", (DL_FUNC) &_duckdb_rapi_rel_insert2, 4}, + {"_duckdb_rapi_rel_join", (DL_FUNC) &_duckdb_rapi_rel_join, 5}, + {"_duckdb_rapi_rel_join2", (DL_FUNC) &_duckdb_rapi_rel_join2, 6}, + {"_duckdb_rapi_rel_limit", (DL_FUNC) &_duckdb_rapi_rel_limit, 2}, + {"_duckdb_rapi_rel_limit2", (DL_FUNC) &_duckdb_rapi_rel_limit2, 3}, + {"_duckdb_rapi_rel_names", (DL_FUNC) &_duckdb_rapi_rel_names, 1}, + {"_duckdb_rapi_rel_names2", (DL_FUNC) &_duckdb_rapi_rel_names2, 2}, + {"_duckdb_rapi_rel_order", (DL_FUNC) &_duckdb_rapi_rel_order, 3}, + {"_duckdb_rapi_rel_order2", (DL_FUNC) &_duckdb_rapi_rel_order2, 4}, + {"_duckdb_rapi_rel_project", (DL_FUNC) &_duckdb_rapi_rel_project, 2}, + {"_duckdb_rapi_rel_project2", (DL_FUNC) &_duckdb_rapi_rel_project2, 3}, + {"_duckdb_rapi_rel_set_alias", (DL_FUNC) &_duckdb_rapi_rel_set_alias, 2}, + {"_duckdb_rapi_rel_set_alias2", (DL_FUNC) &_duckdb_rapi_rel_set_alias2, 3}, + {"_duckdb_rapi_rel_set_diff", (DL_FUNC) &_duckdb_rapi_rel_set_diff, 2}, + {"_duckdb_rapi_rel_set_diff2", (DL_FUNC) &_duckdb_rapi_rel_set_diff2, 3}, + {"_duckdb_rapi_rel_set_intersect", (DL_FUNC) &_duckdb_rapi_rel_set_intersect, 2}, + {"_duckdb_rapi_rel_set_intersect2", (DL_FUNC) &_duckdb_rapi_rel_set_intersect2, 3}, + {"_duckdb_rapi_rel_set_symdiff", (DL_FUNC) &_duckdb_rapi_rel_set_symdiff, 2}, + {"_duckdb_rapi_rel_set_symdiff2", (DL_FUNC) &_duckdb_rapi_rel_set_symdiff2, 3}, + {"_duckdb_rapi_rel_sql", (DL_FUNC) &_duckdb_rapi_rel_sql, 2}, + {"_duckdb_rapi_rel_to_altrep", (DL_FUNC) &_duckdb_rapi_rel_to_altrep, 2}, + {"_duckdb_rapi_rel_to_csv", (DL_FUNC) &_duckdb_rapi_rel_to_csv, 3}, + {"_duckdb_rapi_rel_to_csv2", (DL_FUNC) &_duckdb_rapi_rel_to_csv2, 4}, + {"_duckdb_rapi_rel_to_df", (DL_FUNC) &_duckdb_rapi_rel_to_df, 1}, + {"_duckdb_rapi_rel_to_parquet", (DL_FUNC) &_duckdb_rapi_rel_to_parquet, 3}, + {"_duckdb_rapi_rel_to_parquet2", (DL_FUNC) &_duckdb_rapi_rel_to_parquet2, 4}, + {"_duckdb_rapi_rel_to_sql", (DL_FUNC) &_duckdb_rapi_rel_to_sql, 1}, + {"_duckdb_rapi_rel_to_table", (DL_FUNC) &_duckdb_rapi_rel_to_table, 4}, + {"_duckdb_rapi_rel_to_table2", (DL_FUNC) &_duckdb_rapi_rel_to_table2, 5}, + {"_duckdb_rapi_rel_tostring", (DL_FUNC) &_duckdb_rapi_rel_tostring, 2}, + {"_duckdb_rapi_rel_union_all", (DL_FUNC) &_duckdb_rapi_rel_union_all, 2}, + {"_duckdb_rapi_rel_union_all2", (DL_FUNC) &_duckdb_rapi_rel_union_all2, 3}, + {"_duckdb_rapi_release", (DL_FUNC) &_duckdb_rapi_release, 1}, + {"_duckdb_rapi_shutdown", (DL_FUNC) &_duckdb_rapi_shutdown, 1}, + {"_duckdb_rapi_startup", (DL_FUNC) &_duckdb_rapi_startup, 4}, + {"_duckdb_rapi_unlock", (DL_FUNC) &_duckdb_rapi_unlock, 1}, + {"_duckdb_rapi_unregister_arrow", (DL_FUNC) &_duckdb_rapi_unregister_arrow, 2}, + {"_duckdb_rapi_unregister_df", (DL_FUNC) &_duckdb_rapi_unregister_df, 2}, {NULL, NULL, 0} }; } diff --git a/src/include/reltoaltrep.hpp b/src/include/reltoaltrep.hpp index 7037e15e2..0e7736fac 100644 --- a/src/include/reltoaltrep.hpp +++ b/src/include/reltoaltrep.hpp @@ -2,6 +2,8 @@ #include "rapi.hpp" +#include "duckdb/main/query_result.hpp" + namespace duckdb { struct AltrepRelationWrapper { @@ -54,3 +56,5 @@ SEXP rapi_rel_from_altrep_df(SEXP df, bool strict, bool allow_materialized); SEXP rapi_rel_from_any_df(duckdb::conn_eptr_t con, SEXP df, bool allow_materialized); SEXP rapi_rel_to_altrep2(duckdb::rel_extptr_t rel, duckdb::conn_eptr_t con, bool allow_materialization); + +SEXP result_to_df(duckdb::unique_ptr res); diff --git a/src/relational.cpp b/src/relational.cpp index e01142447..d484a6589 100644 --- a/src/relational.cpp +++ b/src/relational.cpp @@ -158,32 +158,6 @@ SEXP rapi_rel_from_any_df(duckdb::conn_eptr_t con, SEXP df, bool allow_materiali return rapi_rel_from_df(con, df, false); } -static SEXP result_to_df(duckdb::unique_ptr res) { - if (res->HasError()) { - stop("%s", res->GetError().c_str()); - } - if (res->type == QueryResultType::STREAM_RESULT) { - res = ((StreamQueryResult &)*res).Materialize(); - } - D_ASSERT(res->type == QueryResultType::MATERIALIZED_RESULT); - auto mat_res = (MaterializedQueryResult *)res.get(); - - writable::integers row_names; - row_names.push_back(NA_INTEGER); - row_names.push_back(-mat_res->RowCount()); - - // TODO this thing we can probably statically cache - writable::strings classes; - classes.push_back("tbl_df"); - classes.push_back("tbl"); - classes.push_back("data.frame"); - - auto df = sexp(duckdb_execute_R_impl(mat_res, false)); - df.attr("class") = classes; - df.attr("row.names") = row_names; - return df; -} - [[cpp11::register]] SEXP rapi_rel_to_df(duckdb::rel_extptr_t rel) { ScopedInterruptHandler signal_handler(rel->rel->context->GetContext()); diff --git a/src/relational2.cpp b/src/relational2.cpp index c2bbfe518..16039a430 100644 --- a/src/relational2.cpp +++ b/src/relational2.cpp @@ -247,7 +247,7 @@ using namespace cpp11; cpp11::writable::list prot = {rel_left, rel_right}; - return rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, res), con, true); + return rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, std::move(res)), con, true); } [[cpp11::register]] SEXP rapi_rel_set_diff2(data_frame left, data_frame right, duckdb::conn_eptr_t con) { @@ -258,7 +258,7 @@ using namespace cpp11; cpp11::writable::list prot = {rel_left, rel_right}; - return rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, res), con, true); + return rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, std::move(res)), con, true); } [[cpp11::register]] SEXP rapi_rel_set_symdiff2(data_frame left, data_frame right, duckdb::conn_eptr_t con) { @@ -273,5 +273,88 @@ using namespace cpp11; cpp11::writable::list prot = {rel_left, rel_right}; - return rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, symdiff), con, true); + return rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, std::move(symdiff)), con, true); +} + +// DuckDB Relations: conversion + +[[cpp11::register]] SEXP rapi_rel_from_sql2(duckdb::conn_eptr_t con, const std::string sql) { + if (!con || !con.get() || !con->conn) { + stop("rel_from_table: Invalid connection"); + } + auto rel = con->conn->RelationFromQuery(sql); + cpp11::writable::list prot = {}; + return rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, std::move(rel)), con, true); +} + +[[cpp11::register]] SEXP rapi_rel_from_table2(duckdb::conn_eptr_t con, const std::string schema_name, + const std::string table_name) { + if (!con || !con.get() || !con->conn) { + stop("rel_from_table: Invalid connection"); + } + auto rel = con->conn->Table(schema_name, table_name); + cpp11::writable::list prot = {}; + return rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, std::move(rel)), con, true); +} + +[[cpp11::register]] SEXP rapi_rel_from_table_function2(duckdb::conn_eptr_t con, const std::string function_name, + list positional_parameters_sexps, list named_parameters_sexps) { + if (!con || !con.get() || !con->conn) { + stop("rel_from_table_function: Invalid connection"); + } + vector positional_parameters; + + for (sexp parameter_sexp : positional_parameters_sexps) { + if (RApiTypes::GetVecSize(parameter_sexp) < 1) { + stop("rel_from_table_function: Can't have zero-length parameter"); + } + positional_parameters.push_back(RApiTypes::SexpToValue(parameter_sexp, 0)); + } + + named_parameter_map_t named_parameters; + + auto names = named_parameters_sexps.names(); + if (names.size() != named_parameters_sexps.size()) { + stop("rel_from_table_function: Named parameters need names"); + } + R_xlen_t named_parameter_idx = 0; + for (sexp parameter_sexp : named_parameters_sexps) { + if (RApiTypes::GetVecSize(parameter_sexp) != 1) { + stop("rel_from_table_function: Need scalar parameter"); + } + named_parameters[names[named_parameter_idx]] = RApiTypes::SexpToValue(parameter_sexp, 0); + named_parameter_idx++; + } + + auto rel = con->conn->TableFunction(function_name, std::move(positional_parameters), std::move(named_parameters)); + return rapi_rel_to_altrep2(make_external("duckdb_relation", std::move(rel)), con, true); +} + +[[cpp11::register]] SEXP rapi_rel_explain2(data_frame df, duckdb::conn_eptr_t con, std::string type, std::string format) { + auto type_enum = EnumUtil::FromString(type); + auto format_enum = EnumUtil::FromString(format); + + auto rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); + + return result_to_df(rel->rel->Explain(type_enum, format_enum)); +} + +[[cpp11::register]] void rapi_rel_to_parquet2(data_frame df, duckdb::conn_eptr_t con, std::string file_name, list options_sexps) { + auto rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); + rel->rel->WriteParquet(file_name, ListToVectorOfValue(options_sexps)); +} + +[[cpp11::register]] void rapi_rel_to_csv2(data_frame df, duckdb::conn_eptr_t con, std::string file_name, list options_sexps) { + auto rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); + rel->rel->WriteCSV(file_name, ListToVectorOfValue(options_sexps)); +} + +[[cpp11::register]] void rapi_rel_to_table2(data_frame df, duckdb::conn_eptr_t con, std::string schema_name, std::string table_name, bool temporary) { + auto rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); + rel->rel->Create(schema_name, table_name, temporary); +} + +[[cpp11::register]] void rapi_rel_insert2(data_frame df, duckdb::conn_eptr_t con, std::string schema_name, std::string table_name) { + auto rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); + rel->rel->Insert(schema_name, table_name); } diff --git a/src/reltoaltrep.cpp b/src/reltoaltrep.cpp index 7135b17d6..e6bff4651 100644 --- a/src/reltoaltrep.cpp +++ b/src/reltoaltrep.cpp @@ -485,6 +485,32 @@ SEXP rapi_rel_to_altrep2(duckdb::rel_extptr_t rel, duckdb::conn_eptr_t con, bool return res; } +SEXP result_to_df(duckdb::unique_ptr res) { + if (res->HasError()) { + stop("%s", res->GetError().c_str()); + } + if (res->type == QueryResultType::STREAM_RESULT) { + res = ((StreamQueryResult &)*res).Materialize(); + } + D_ASSERT(res->type == QueryResultType::MATERIALIZED_RESULT); + auto mat_res = (MaterializedQueryResult *)res.get(); + + writable::integers row_names; + row_names.push_back(NA_INTEGER); + row_names.push_back(-mat_res->RowCount()); + + // TODO this thing we can probably statically cache + writable::strings classes; + classes.push_back("tbl_df"); + classes.push_back("tbl"); + classes.push_back("data.frame"); + + auto df = sexp(duckdb_execute_R_impl(mat_res, false)); + df.attr("class") = classes; + df.attr("row.names") = row_names; + return df; +} + // exception required as long as r-lib/decor#6 remains // clang-format off [[cpp11::init]] void RelToAltrep_Initialize(DllInfo* dll) { From 95c775ce68720597fb38a72f353427623ba1a795 Mon Sep 17 00:00:00 2001 From: Antonov548 Date: Wed, 29 Jan 2025 11:16:30 +0100 Subject: [PATCH 43/69] add `expr_reference2` and `rel_join2` --- R/relational.R | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/R/relational.R b/R/relational.R index a94a8d324..d0811e825 100644 --- a/R/relational.R +++ b/R/relational.R @@ -18,6 +18,22 @@ expr_reference <- function(names, table = NULL) { rethrow_rapi_expr_reference(names) } + +#' Create a column reference expression +#' @param names the column name to be referenced, could be a list to refer to schema.table.column etc. +#' @param table the optional table name or a relation object to be referenced +#' @return a column reference expression +#' @noRd +#' @examples +#' col_ref_expr <- expr_reference("some_column_name") +#' col_ref_expr2 <- expr_reference("some_column_name", "some_table_name") +expr_reference2 <- function(names, table = NULL) { + if (is.character(table) && !identical(table, "")) { + names <- c(table, names) + } + rethrow_rapi_expr_reference(names) +} + #' Create a constant expression #' @param val the constant value #' @return a constant expression @@ -338,6 +354,19 @@ rel_join <- function(left, right, conds, rethrow_rapi_rel_join(left, right, conds, join, join_ref_type) } +rel_join2 <- function(left, right, con, conds, + join = c("inner", "left", "right", "outer", "cross", "semi", "anti"), + join_ref_type = c("regular", "natural", "cross", "positional", "asof")) { + join <- match.arg(join) + join_ref_type <- match.arg(join_ref_type) + # the ref type is naturally regular. Users won't write rel_join(left, right, conds, "cross", "cross") + # so we update it here. + if (join == "cross" && join_ref_type == "regular") { + join_ref_type <- "cross" + } + rethrow_rapi_rel_join2(left, right, con@conn_ref, conds, join, join_ref_type) +} + #' UNION ALL on two DuckDB relation objects #' @param rel_a a DuckDB relation object #' @param rel_b a DuckDB relation object From 78d6a34b178cb0a88a8af06ebe7aefd675d86965 Mon Sep 17 00:00:00 2001 From: Antonov548 Date: Wed, 29 Jan 2025 11:17:23 +0100 Subject: [PATCH 44/69] add api2 tests --- tests/testthat/test-rel_api2.R | 72 ++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 tests/testthat/test-rel_api2.R diff --git a/tests/testthat/test-rel_api2.R b/tests/testthat/test-rel_api2.R new file mode 100644 index 000000000..996729dd0 --- /dev/null +++ b/tests/testthat/test-rel_api2.R @@ -0,0 +1,72 @@ +test_that("relational anti_join(join_by(a)) order-preserving 2", { + # Autogenerated + drv <- duckdb() + con <- dbConnect(drv) + experimental <- FALSE + invisible( + dbExecute(con, 'CREATE MACRO "___eq_na_matches_na"(x, y) AS (x IS NOT DISTINCT FROM y)') + ) + df1 <- data.frame(a = 1:4, b = 2) + "anti_join" + df2 <- rel_set_alias2(df1, con, "lhs") + df3 <- data.frame(a = 2:5, b = 2) + "anti_join" + df4 <- rel_set_alias2(df3, con, "rhs") + "anti_join" + df5 <- rel_project2( + df2, + con, + list( + { + tmp_expr <- expr_reference("a") + expr_set_alias(tmp_expr, "a") + tmp_expr + }, + { + tmp_expr <- expr_reference("b") + expr_set_alias(tmp_expr, "b") + tmp_expr + }, + { + tmp_expr <- expr_window(expr_function("row_number", list()), list(), list(), offset_expr = NULL, default_expr = NULL) + expr_set_alias(tmp_expr, "___row_number_x") + tmp_expr + } + ) + ) + "anti_join" + df6 <- rel_join2( + df5, + df4, + con, + list( + expr_function("___eq_na_matches_na", list(expr_reference("a", rel5), expr_reference("a", rel4))) + ), + "anti" + ) + "anti_join" + df7 <- rel_order2(df6, con, list(expr_reference("___row_number_x", rel5))) + "anti_join" + df8 <- rel_project2( + df7, + con, + list( + { + tmp_expr <- expr_reference("a") + expr_set_alias(tmp_expr, "a") + tmp_expr + }, + { + tmp_expr <- expr_reference("b") + expr_set_alias(tmp_expr, "b") + tmp_expr + } + ) + ) + df8 + expect_identical( + df8, + data.frame(a = 1L, b = 2) + ) + dbDisconnect(con, shutdown = TRUE) +}) From 245df5404a67e7707cca502ef73fcee1e46ec4f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Wed, 12 Feb 2025 09:43:32 +0100 Subject: [PATCH 45/69] order-enforcing is easier --- tests/testthat/test-rel_api2.R | 49 ++++------------------------------ 1 file changed, 5 insertions(+), 44 deletions(-) diff --git a/tests/testthat/test-rel_api2.R b/tests/testthat/test-rel_api2.R index 996729dd0..0f672a867 100644 --- a/tests/testthat/test-rel_api2.R +++ b/tests/testthat/test-rel_api2.R @@ -1,4 +1,4 @@ -test_that("relational anti_join(join_by(a)) order-preserving 2", { +test_that("relational anti_join(join_by(a)) order-enforcing 2", { # Autogenerated drv <- duckdb() con <- dbConnect(drv) @@ -13,30 +13,8 @@ test_that("relational anti_join(join_by(a)) order-preserving 2", { "anti_join" df4 <- rel_set_alias2(df3, con, "rhs") "anti_join" - df5 <- rel_project2( + df5 <- rel_join2( df2, - con, - list( - { - tmp_expr <- expr_reference("a") - expr_set_alias(tmp_expr, "a") - tmp_expr - }, - { - tmp_expr <- expr_reference("b") - expr_set_alias(tmp_expr, "b") - tmp_expr - }, - { - tmp_expr <- expr_window(expr_function("row_number", list()), list(), list(), offset_expr = NULL, default_expr = NULL) - expr_set_alias(tmp_expr, "___row_number_x") - tmp_expr - } - ) - ) - "anti_join" - df6 <- rel_join2( - df5, df4, con, list( @@ -45,27 +23,10 @@ test_that("relational anti_join(join_by(a)) order-preserving 2", { "anti" ) "anti_join" - df7 <- rel_order2(df6, con, list(expr_reference("___row_number_x", rel5))) - "anti_join" - df8 <- rel_project2( - df7, - con, - list( - { - tmp_expr <- expr_reference("a") - expr_set_alias(tmp_expr, "a") - tmp_expr - }, - { - tmp_expr <- expr_reference("b") - expr_set_alias(tmp_expr, "b") - tmp_expr - } - ) - ) - df8 + df6 <- rel_order2(df5, con, list(expr_reference("a"), expr_reference("b"))) + df6 expect_identical( - df8, + df6, data.frame(a = 1L, b = 2) ) dbDisconnect(con, shutdown = TRUE) From b1861ea044c1911d753f09ac98a6eef6508ad6fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Wed, 12 Feb 2025 09:47:14 +0100 Subject: [PATCH 46/69] Tweaks --- R/relational.R | 5 ++++- tests/testthat/test-rel_api2.R | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/R/relational.R b/R/relational.R index d0811e825..f437a152a 100644 --- a/R/relational.R +++ b/R/relational.R @@ -27,7 +27,10 @@ expr_reference <- function(names, table = NULL) { #' @examples #' col_ref_expr <- expr_reference("some_column_name") #' col_ref_expr2 <- expr_reference("some_column_name", "some_table_name") -expr_reference2 <- function(names, table = NULL) { +expr_reference2 <- function(names, table = NULL, con = NULL) { + if (inherits(table, "data.frame")) { + names <- c(rel_alias2(table, con), names) + } if (is.character(table) && !identical(table, "")) { names <- c(table, names) } diff --git a/tests/testthat/test-rel_api2.R b/tests/testthat/test-rel_api2.R index 0f672a867..f7c8e4b43 100644 --- a/tests/testthat/test-rel_api2.R +++ b/tests/testthat/test-rel_api2.R @@ -18,7 +18,7 @@ test_that("relational anti_join(join_by(a)) order-enforcing 2", { df4, con, list( - expr_function("___eq_na_matches_na", list(expr_reference("a", rel5), expr_reference("a", rel4))) + expr_function("___eq_na_matches_na", list(expr_reference2("a", df2, con), expr_reference2("a", df4, con))) ), "anti" ) From 1b30936bca166915e0996382a224624ef92cda6e Mon Sep 17 00:00:00 2001 From: Antonov548 Date: Thu, 13 Feb 2025 22:00:44 +0100 Subject: [PATCH 47/69] add more tests --- tests/testthat/test-rel_api2.R | 834 +++++++++++++++++++++++++++++++++ 1 file changed, 834 insertions(+) diff --git a/tests/testthat/test-rel_api2.R b/tests/testthat/test-rel_api2.R index f7c8e4b43..91fdd6b74 100644 --- a/tests/testthat/test-rel_api2.R +++ b/tests/testthat/test-rel_api2.R @@ -31,3 +31,837 @@ test_that("relational anti_join(join_by(a)) order-enforcing 2", { ) dbDisconnect(con, shutdown = TRUE) }) + +test_that("relational anti_join(join_by(a)) order-enforcing 2", { + # Autogenerated + drv <- duckdb() + con <- dbConnect(drv) + experimental <- FALSE + invisible( + dbExecute(con, 'CREATE MACRO "___eq_na_matches_na"(x, y) AS (x IS NOT DISTINCT FROM y)') + ) + df1 <- data.frame(a = 1:4, b = 2) + "anti_join" + df2 <- rel_set_alias2(df1, con, "lhs") + df3 <- data.frame(a = 2:5, b = 2) + "anti_join" + df4 <- rel_set_alias2(df3, con, "rhs") + "anti_join" + df5 <- rel_join2( + df2, + df4, + con, + list( + expr_function("___eq_na_matches_na", list(expr_reference2("a", df2, con), expr_reference2("a", df4, con))) + ), + "anti" + ) + "arrange" + df6 <- rel_order2(df5, con, list(expr_reference("a"), expr_reference("b"))) + df6 + expect_identical( + df6, + data.frame(a = 1L, b = 2) + ) + dbDisconnect(con, shutdown = TRUE) +}) + +test_that("relational arrange(a) order-preserving 2", { + # Autogenerated + drv <- duckdb() + con <- dbConnect(drv) + experimental <- FALSE + df1 <- data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L)) + + "arrange" + df2 <- rel_project2( + df1, + con, + list( + { + tmp_expr <- expr_reference2("a") + expr_set_alias(tmp_expr, "a") + tmp_expr + }, + { + tmp_expr <- expr_reference2("b") + expr_set_alias(tmp_expr, "b") + tmp_expr + }, + { + tmp_expr <- expr_reference2("g") + expr_set_alias(tmp_expr, "g") + tmp_expr + }, + { + tmp_expr <- expr_window(expr_function("row_number", list()), list(), list(), offset_expr = NULL, default_expr = NULL) + expr_set_alias(tmp_expr, "___row_number") + tmp_expr + } + ) + ) + "arrange" + df3 <- rel_order2(df2, con, list(expr_reference2("a"), expr_reference2("___row_number"))) + "arrange" + df4 <- rel_project2( + df3, + con, + list( + { + tmp_expr <- expr_reference("a") + expr_set_alias(tmp_expr, "a") + tmp_expr + }, + { + tmp_expr <- expr_reference("b") + expr_set_alias(tmp_expr, "b") + tmp_expr + }, + { + tmp_expr <- expr_reference("g") + expr_set_alias(tmp_expr, "g") + tmp_expr + } + ) + ) + expect_identical( + df4, + data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L)) + ) + dbDisconnect(con, shutdown = TRUE) +}) + +test_that("relational arrange(g) order-enforcing 2", { + # Autogenerated + drv <- duckdb() + con <- dbConnect(drv) + experimental <- FALSE + df1 <- data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L)) + + "arrange" + df2 <- rel_project2( + df1, + con, + list( + { + tmp_expr <- expr_reference("a") + expr_set_alias(tmp_expr, "a") + tmp_expr + }, + { + tmp_expr <- expr_reference("b") + expr_set_alias(tmp_expr, "b") + tmp_expr + }, + { + tmp_expr <- expr_reference("g") + expr_set_alias(tmp_expr, "g") + tmp_expr + }, + { + tmp_expr <- expr_window(expr_function("row_number", list()), list(), list(), offset_expr = NULL, default_expr = NULL) + expr_set_alias(tmp_expr, "___row_number") + tmp_expr + } + ) + ) + "arrange" + df3 <- rel_order2(df2, con, list(expr_reference("g"), expr_reference("___row_number"))) + "arrange" + df4 <- rel_project2( + df3, + con, + list( + { + tmp_expr <- expr_reference("a") + expr_set_alias(tmp_expr, "a") + tmp_expr + }, + { + tmp_expr <- expr_reference("b") + expr_set_alias(tmp_expr, "b") + tmp_expr + }, + { + tmp_expr <- expr_reference("g") + expr_set_alias(tmp_expr, "g") + tmp_expr + } + ) + ) + expect_identical( + df4, + data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L)) + ) + dbDisconnect(con, shutdown = TRUE) +}) + +test_that("relational arrange() order-enforcing 2", { + # Autogenerated + drv <- duckdb() + con <- dbConnect(drv) + experimental <- FALSE + df1 <- data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L)) + + "arrange" + df2 <- rel_order2( + df1, + con, + list(expr_reference("a"), expr_reference("b"), expr_reference("g")) + ) + expect_identical( + df2, + data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L)) + ) + dbDisconnect(con, shutdown = TRUE) +}) + +test_that("relational arrange(a) order-enforcing 2", { + # Autogenerated + drv <- duckdb() + con <- dbConnect(drv) + experimental <- FALSE + df1 <- data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L)) + + "arrange" + df2 <- rel_order2( + df1, + con, + list(expr_reference("a"), expr_reference("b"), expr_reference("g")) + ) + expect_identical( + df2, + data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L)) + ) + dbDisconnect(con, shutdown = TRUE) +}) + +test_that("relational arrange(g) order-enforcing 2", { + # Autogenerated + drv <- duckdb() + con <- dbConnect(drv) + experimental <- FALSE + df1 <- data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L)) + + "arrange" + rel1 <- rel_from_df(con, df1, experimental = experimental) + "arrange" + rel2 <- rel_order(rel1, list(expr_reference("g"))) + "arrange" + rel3 <- rel_order( + rel2, + list(expr_reference("a"), expr_reference("b"), expr_reference("g")) + ) + rel3 + out <- rel_to_altrep(rel3) + expect_identical( + out, + data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L)) + ) + dbDisconnect(con, shutdown = TRUE) +}) + +test_that("relational arrange(g, a) order-enforcing 2", { + # Autogenerated + drv <- duckdb() + con <- dbConnect(drv) + experimental <- FALSE + df1 <- data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L)) + + "arrange" + rel1 <- rel_from_df(con, df1, experimental = experimental) + "arrange" + rel2 <- rel_order(rel1, list(expr_reference("g"), expr_reference("a"))) + "arrange" + rel3 <- rel_order( + rel2, + list(expr_reference("a"), expr_reference("b"), expr_reference("g")) + ) + rel3 + out <- rel_to_altrep(rel3) + expect_identical( + out, + data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L)) + ) + dbDisconnect(con, shutdown = TRUE) +}) + +test_that("relational arrange(a, g) order-enforcing 2", { + # Autogenerated + drv <- duckdb() + con <- dbConnect(drv) + experimental <- FALSE + df1 <- data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L)) + + df2 <- rel_order2( + df1, + con, + list(expr_reference("a"), expr_reference("b"), expr_reference("g")) + ) + expect_identical( + df2, + data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L)) + ) + dbDisconnect(con, shutdown = TRUE) +}) + +test_that("relational count() order-preserving 2", { + # Autogenerated + drv <- duckdb() + con <- dbConnect(drv) + experimental <- FALSE + invisible(dbExecute(con, 'CREATE MACRO "n"() AS CAST(COUNT(*) AS int32)')) + df1 <- data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L)) + + "count" + df2 <- rel_aggregate2( + df1, + con, + groups = list(), + aggregates = list( + { + tmp_expr <- expr_function("n", list()) + expr_set_alias(tmp_expr, "n") + tmp_expr + } + ) + ) + expect_identical( + df2, + data.frame(n = 6L) + ) + dbDisconnect(con, shutdown = TRUE) +}) + +test_that("relational count(a) order-preserving 2", { + # Autogenerated + drv <- duckdb() + con <- dbConnect(drv) + experimental <- FALSE + invisible(dbExecute(con, 'CREATE MACRO "n"() AS CAST(COUNT(*) AS int32)')) + df1 <- data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L)) + + "count" + df2 <- rel_aggregate2( + df1, + con, + groups = list( + a = { + tmp_expr <- expr_reference("a") + expr_set_alias(tmp_expr, "a") + tmp_expr + } + ), + aggregates = list( + { + tmp_expr <- expr_function("n", list()) + expr_set_alias(tmp_expr, "n") + tmp_expr + } + ) + ) + "count" + df3 <- rel_order2( + df2, + con, + list( + { + tmp_expr <- expr_reference("a") + expr_set_alias(tmp_expr, "a") + tmp_expr + } + ) + ) + expect_identical( + df3, + data.frame(a = seq(1, 6, by = 1), n = 1L) + ) + dbDisconnect(con, shutdown = TRUE) +}) + +test_that("relational count(b) order-preserving 2", { + # Autogenerated + drv <- duckdb() + con <- dbConnect(drv) + experimental <- FALSE + invisible(dbExecute(con, 'CREATE MACRO "n"() AS CAST(COUNT(*) AS int32)')) + df1 <- data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L)) + + "count" + df2 <- rel_aggregate2( + df1, + con, + groups = list( + b = { + tmp_expr <- expr_reference("b") + expr_set_alias(tmp_expr, "b") + tmp_expr + } + ), + aggregates = list( + { + tmp_expr <- expr_function("n", list()) + expr_set_alias(tmp_expr, "n") + tmp_expr + } + ) + ) + "count" + df3 <- rel_order2( + df2, + con, + list( + { + tmp_expr <- expr_reference("b") + expr_set_alias(tmp_expr, "b") + tmp_expr + } + ) + ) + expect_identical( + df3, + data.frame(b = 2, n = 6L) + ) + dbDisconnect(con, shutdown = TRUE) +}) + +test_that("relational distinct() order-preserving 2", { + # Autogenerated + drv <- duckdb() + con <- dbConnect(drv) + experimental <- FALSE + df1 <- data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L)) + + "distinct" + df2 <- rel_project2( + df1, + con, + list( + { + tmp_expr <- expr_reference("a") + expr_set_alias(tmp_expr, "a") + tmp_expr + }, + { + tmp_expr <- expr_reference("b") + expr_set_alias(tmp_expr, "b") + tmp_expr + }, + { + tmp_expr <- expr_reference("g") + expr_set_alias(tmp_expr, "g") + tmp_expr + }, + { + tmp_expr <- expr_window(expr_function("row_number", list()), list(), list(), offset_expr = NULL, default_expr = NULL) + expr_set_alias(tmp_expr, "___row_number") + tmp_expr + } + ) + ) + "distinct" + df3 <- rel_project2( + df2, + con, + list( + { + tmp_expr <- expr_reference("a") + expr_set_alias(tmp_expr, "a") + tmp_expr + }, + { + tmp_expr <- expr_reference("b") + expr_set_alias(tmp_expr, "b") + tmp_expr + }, + { + tmp_expr <- expr_reference("g") + expr_set_alias(tmp_expr, "g") + tmp_expr + }, + expr_reference("___row_number"), + { + tmp_expr <- expr_window( + expr_function("row_number", list()), + list( + a = { + tmp_expr <- expr_reference("a") + expr_set_alias(tmp_expr, "a") + tmp_expr + }, + b = { + tmp_expr <- expr_reference("b") + expr_set_alias(tmp_expr, "b") + tmp_expr + }, + g = { + tmp_expr <- expr_reference("g") + expr_set_alias(tmp_expr, "g") + tmp_expr + } + ), + list(expr_reference("___row_number")), + offset_expr = NULL, + default_expr = NULL + ) + expr_set_alias(tmp_expr, "___row_number_by") + tmp_expr + } + ) + ) + "distinct" + df4 <- rel_filter2( + df3, + con, + list( + expr_comparison( + "==", + list( + expr_reference("___row_number_by"), + if ("experimental" %in% names(formals(expr_constant))) { + expr_constant(1L, experimental = experimental) + } else { + expr_constant(1L) + } + ) + ) + ) + ) + "distinct" + df5 <- rel_order2(df4, con, list(expr_reference("___row_number"))) + "distinct" + df6 <- rel_project2( + df5, + con, + list( + { + tmp_expr <- expr_reference("a") + expr_set_alias(tmp_expr, "a") + tmp_expr + }, + { + tmp_expr <- expr_reference("b") + expr_set_alias(tmp_expr, "b") + tmp_expr + }, + { + tmp_expr <- expr_reference("g") + expr_set_alias(tmp_expr, "g") + tmp_expr + } + ) + ) + expect_identical( + df6, + data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L)) + ) + dbDisconnect(con, shutdown = TRUE) +}) + +test_that("relational distinct(a) order-preserving 2", { + # Autogenerated + drv <- duckdb() + con <- dbConnect(drv) + experimental <- FALSE + df1 <- data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L)) + + "distinct" + df2 <- rel_project2( + df1, + con, + list( + { + tmp_expr <- expr_reference("a") + expr_set_alias(tmp_expr, "a") + tmp_expr + }, + { + tmp_expr <- expr_reference("b") + expr_set_alias(tmp_expr, "b") + tmp_expr + }, + { + tmp_expr <- expr_reference("g") + expr_set_alias(tmp_expr, "g") + tmp_expr + }, + { + tmp_expr <- expr_window(expr_function("row_number", list()), list(), list(), offset_expr = NULL, default_expr = NULL) + expr_set_alias(tmp_expr, "___row_number") + tmp_expr + } + ) + ) + "distinct" + df3 <- rel_project2( + df2, + con, + list( + { + tmp_expr <- expr_reference("a") + expr_set_alias(tmp_expr, "a") + tmp_expr + }, + expr_reference("___row_number"), + { + tmp_expr <- expr_window( + expr_function("row_number", list()), + list( + a = { + tmp_expr <- expr_reference("a") + expr_set_alias(tmp_expr, "a") + tmp_expr + } + ), + list(expr_reference("___row_number")), + offset_expr = NULL, + default_expr = NULL + ) + expr_set_alias(tmp_expr, "___row_number_by") + tmp_expr + } + ) + ) + "distinct" + df4 <- rel_filter2( + df3, + con, + list( + expr_comparison( + "==", + list( + expr_reference("___row_number_by"), + if ("experimental" %in% names(formals(expr_constant))) { + expr_constant(1L, experimental = experimental) + } else { + expr_constant(1L) + } + ) + ) + ) + ) + "distinct" + df5 <- rel_order2(df4, con, list(expr_reference("___row_number"))) + "distinct" + df6 <- rel_project2( + df5, + con, + list( + { + tmp_expr <- expr_reference("a") + expr_set_alias(tmp_expr, "a") + tmp_expr + } + ) + ) + expect_identical( + df6, + data.frame(a = seq(1, 6, by = 1)) + ) + dbDisconnect(con, shutdown = TRUE) +}) + +test_that("relational union_all(data.frame(a = 1L, b = 3, g = 2L)) %>% distinct(g) order-preserving", { + # Autogenerated + drv <- duckdb() + con <- dbConnect(drv) + experimental <- FALSE + df1 <- data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L)) + + "union_all" + df2 <- rel_project2( + df1, + con, + list( + { + tmp_expr <- expr_reference("a") + expr_set_alias(tmp_expr, "a") + tmp_expr + }, + { + tmp_expr <- expr_reference("b") + expr_set_alias(tmp_expr, "b") + tmp_expr + }, + { + tmp_expr <- expr_reference("g") + expr_set_alias(tmp_expr, "g") + tmp_expr + }, + { + tmp_expr <- expr_window(expr_function("row_number", list()), list(), list(), offset_expr = NULL, default_expr = NULL) + expr_set_alias(tmp_expr, "___row_number_x") + tmp_expr + }, + { + tmp_expr <- if ("experimental" %in% names(formals(expr_constant))) { + expr_constant(NA_integer_, experimental = experimental) + } else { + expr_constant(NA_integer_) + } + expr_set_alias(tmp_expr, "___row_number_y") + tmp_expr + } + ) + ) + "union_all" + df3 <- rel_project2( + df2, + con, + list( + { + tmp_expr <- expr_reference("a") + expr_set_alias(tmp_expr, "a") + tmp_expr + }, + { + tmp_expr <- expr_reference("b") + expr_set_alias(tmp_expr, "b") + tmp_expr + }, + { + tmp_expr <- expr_reference("g") + expr_set_alias(tmp_expr, "g") + tmp_expr + }, + { + tmp_expr <- if ("experimental" %in% names(formals(expr_constant))) { + expr_constant(NA_integer_, experimental = experimental) + } else { + expr_constant(NA_integer_) + } + expr_set_alias(tmp_expr, "___row_number_x") + tmp_expr + }, + { + tmp_expr <- expr_window(expr_function("row_number", list()), list(), list(), offset_expr = NULL, default_expr = NULL) + expr_set_alias(tmp_expr, "___row_number_y") + tmp_expr + } + ) + ) + "union_all" + df4 <- rel_union_all2(df2, df3, con) + "union_all" + df5 <- rel_order2( + df4, + con, + list(expr_reference("___row_number_x"), expr_reference("___row_number_y")) + ) + "union_all" + df6 <- rel_project2( + df5, + con, + list( + { + tmp_expr <- expr_reference("a") + expr_set_alias(tmp_expr, "a") + tmp_expr + }, + { + tmp_expr <- expr_reference("b") + expr_set_alias(tmp_expr, "b") + tmp_expr + }, + { + tmp_expr <- expr_reference("g") + expr_set_alias(tmp_expr, "g") + tmp_expr + } + ) + ) + "distinct" + df7 <- rel_project2( + df6, + con, + list( + { + tmp_expr <- expr_reference("a") + expr_set_alias(tmp_expr, "a") + tmp_expr + }, + { + tmp_expr <- expr_reference("b") + expr_set_alias(tmp_expr, "b") + tmp_expr + }, + { + tmp_expr <- expr_reference("g") + expr_set_alias(tmp_expr, "g") + tmp_expr + }, + { + tmp_expr <- expr_window(expr_function("row_number", list()), list(), list(), offset_expr = NULL, default_expr = NULL) + expr_set_alias(tmp_expr, "___row_number") + tmp_expr + } + ) + ) + "distinct" + df8 <- rel_project2( + df7, + con, + list( + { + tmp_expr <- expr_reference("g") + expr_set_alias(tmp_expr, "g") + tmp_expr + }, + expr_reference("___row_number"), + { + tmp_expr <- expr_window( + expr_function("row_number", list()), + list( + g = { + tmp_expr <- expr_reference("g") + expr_set_alias(tmp_expr, "g") + tmp_expr + } + ), + list(expr_reference("___row_number")), + offset_expr = NULL, + default_expr = NULL + ) + expr_set_alias(tmp_expr, "___row_number_by") + tmp_expr + } + ) + ) + "distinct" + df9 <- rel_filter2( + df8, + con, + list( + expr_comparison( + "==", + list( + expr_reference("___row_number_by"), + if ("experimental" %in% names(formals(expr_constant))) { + expr_constant(1L, experimental = experimental) + } else { + expr_constant(1L) + } + ) + ) + ) + ) + "distinct" + df10 <- rel_order2(df9, con, list(expr_reference("___row_number"))) + "distinct" + df11 <- rel_project2( + df10, + con, + list( + { + tmp_expr <- expr_reference("g") + expr_set_alias(tmp_expr, "g") + tmp_expr + } + ) + ) + expect_identical( + df11, + data.frame(g = 1:3) + ) + dbDisconnect(con, shutdown = TRUE) +}) From 6f2603c93c0098b0db4b27db33c38ae2d50d5d2a Mon Sep 17 00:00:00 2001 From: Antonov548 Date: Tue, 18 Feb 2025 18:16:52 +0100 Subject: [PATCH 48/69] fix typo --- R/relational.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/relational.R b/R/relational.R index f437a152a..da3a89685 100644 --- a/R/relational.R +++ b/R/relational.R @@ -419,7 +419,7 @@ rel_distinct <- function(rel) { #' rel <- rel_from_df(con, mtcars) #' rel2 <- rel_distinct(rel) rel_distinct2 <- function(df, con) { - rethrow_rapi_rel_distinct(df, con@conn_ref) + rethrow_rapi_rel_distinct2(df, con@conn_ref) } #' SET INTERSECT on two DuckDB relation objects From c998e9dcee11cc2f299ff3f5f72d44c6ef5756a6 Mon Sep 17 00:00:00 2001 From: Antonov548 Date: Tue, 18 Feb 2025 18:17:45 +0100 Subject: [PATCH 49/69] add tests for `rel_filter2` and `rel_distinct2` --- tests/testthat/test-rel_api2.R | 212 +++++++++++++++++++++++++++++++++ 1 file changed, 212 insertions(+) diff --git a/tests/testthat/test-rel_api2.R b/tests/testthat/test-rel_api2.R index 91fdd6b74..cf6be28f3 100644 --- a/tests/testthat/test-rel_api2.R +++ b/tests/testthat/test-rel_api2.R @@ -865,3 +865,215 @@ test_that("relational union_all(data.frame(a = 1L, b = 3, g = 2L)) %>% distinct( ) dbDisconnect(con, shutdown = TRUE) }) + +test_that("relational filter(a == 1) order-enforcing", { + # Autogenerated + drv <- duckdb() + con <- dbConnect(drv) + experimental <- FALSE + df1 <- data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L)) + + "filter" + df2 <- rel_filter2( + df1, + con, + list( + expr_comparison( + "==", + list( + expr_reference("a"), + if ("experimental" %in% names(formals(expr_constant))) { + expr_constant(1, experimental = experimental) + } else { + expr_constant(1) + } + ) + ) + ) + ) + "arrange" + df3 <- rel_order2( + df2, + con, + list(expr_reference("a"), expr_reference("b"), expr_reference("g")) + ) + expect_identical( + df3, + data.frame(a = 1, b = 2, g = 1L) + ) + dbDisconnect(con, shutdown = TRUE) +}) + +test_that("relational filter(a %in% 2:3 & g == 2) order-enforcing", { + # Autogenerated + drv <- duckdb() + con <- dbConnect(drv) + experimental <- FALSE + invisible(rapi_load_rfuns(drv@database_ref)) + invisible(dbExecute(con, 'CREATE MACRO "&"(x, y) AS (x AND y)')) + invisible(dbExecute(con, 'CREATE MACRO "___coalesce"(x, y) AS COALESCE(x, y)')) + invisible(dbExecute(con, 'CREATE MACRO "|"(x, y) AS (x OR y)')) + df1 <- data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L)) + + "filter" + df2 <- rel_filter2( + df1, + con, + list( + expr_function( + "&", + list( + expr_function( + "___coalesce", + list( + expr_function( + "|", + list( + expr_function( + "r_base::==", + list( + expr_reference("a"), + if ("experimental" %in% names(formals(expr_constant))) { + expr_constant(2L, experimental = experimental) + } else { + expr_constant(2L) + } + ) + ), + expr_function( + "r_base::==", + list( + expr_reference("a"), + if ("experimental" %in% names(formals(expr_constant))) { + expr_constant(3L, experimental = experimental) + } else { + expr_constant(3L) + } + ) + ) + ) + ), + if ("experimental" %in% names(formals(expr_constant))) { + expr_constant(FALSE, experimental = experimental) + } else { + expr_constant(FALSE) + } + ) + ), + expr_comparison( + "==", + list( + expr_reference("g"), + if ("experimental" %in% names(formals(expr_constant))) { + expr_constant(2, experimental = experimental) + } else { + expr_constant(2) + } + ) + ) + ) + ) + ) + ) + "arrange" + df3 <- rel_order2( + df2, + con, + list(expr_reference("a"), expr_reference("b"), expr_reference("g")) + ) + expect_identical( + df3, + data.frame(a = c(2, 3), b = 2, g = 2L) + ) + dbDisconnect(con, shutdown = TRUE) +}) + +# +test_that("relational summarise(c = mean(a)) order-enforcing", { + # Autogenerated + drv <- duckdb() + con <- dbConnect(drv) + experimental <- FALSE + df1 <- data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L)) + + "summarise" + df2 <- rel_aggregate2( + df1, + con, + groups = list(), + aggregates = list( + { + tmp_expr <- expr_function("mean", list(expr_reference("a"))) + expr_set_alias(tmp_expr, "c") + tmp_expr + } + ) + ) + "summarise" + df3 <- rel_distinct2(df2, con) + "arrange" + df4 <- rel_order2(df3, con, list(expr_reference("c"))) + expect_identical( + df4, + data.frame(c = 3.5) + ) + dbDisconnect(con, shutdown = TRUE) +}) + +test_that("relational summarise(c = mean(a), .by = b) order-enforcing", { + # Autogenerated + drv <- duckdb() + con <- dbConnect(drv) + experimental <- FALSE + df1 <- data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L)) + + "summarise" + df2 <- rel_aggregate2( + df1, + con, + groups = list(expr_reference("b")), + aggregates = list( + { + tmp_expr <- expr_function("mean", list(expr_reference("a"))) + expr_set_alias(tmp_expr, "c") + tmp_expr + } + ) + ) + "arrange" + df3 <- rel_order2(df2, con, list(expr_reference("b"), expr_reference("c"))) + expect_identical( + df3, + data.frame(b = 2, c = 3.5) + ) + dbDisconnect(con, shutdown = TRUE) +}) + +test_that("relational summarise(c = mean(a), .by = g) order-enforcing", { + # Autogenerated + drv <- duckdb() + con <- dbConnect(drv) + experimental <- FALSE + df1 <- data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L)) + + "summarise" + df2 <- rel_aggregate2( + df1, + con, + groups = list(expr_reference("g")), + aggregates = list( + { + tmp_expr <- expr_function("mean", list(expr_reference("a"))) + expr_set_alias(tmp_expr, "c") + tmp_expr + } + ) + ) + "arrange" + df3 <- rel_order2(df2, con, list(expr_reference("g"), expr_reference("c"))) + expect_identical( + df3, + data.frame(g = 1:3, c = c(1, 2.5, 5)) + ) + dbDisconnect(con, shutdown = TRUE) +}) From d7cfd32420cbce1940514028ab7b7aec152def3c Mon Sep 17 00:00:00 2001 From: Antonov548 Date: Tue, 18 Feb 2025 18:21:55 +0100 Subject: [PATCH 50/69] add tests for `rel_set_intersect2` and `rel_set_diff2` --- tests/testthat/test-rel_api2.R | 38 ++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/tests/testthat/test-rel_api2.R b/tests/testthat/test-rel_api2.R index cf6be28f3..9584bc63a 100644 --- a/tests/testthat/test-rel_api2.R +++ b/tests/testthat/test-rel_api2.R @@ -1077,3 +1077,41 @@ test_that("relational summarise(c = mean(a), .by = g) order-enforcing", { ) dbDisconnect(con, shutdown = TRUE) }) + +test_that("relational intersect() order-enforcing", { + # Autogenerated + drv <- duckdb() + con <- dbConnect(drv) + experimental <- FALSE + df1 <- data.frame(a = 1:4, b = 2) + df2 <- data.frame(a = 2:5, b = 2) + + "intersect" + df3 <- rel_set_intersect2(df1, df2, con) + "arrange" + df4 <- rel_order2(df3, con, list(expr_reference("a"), expr_reference("b"))) + expect_identical( + df4, + data.frame(a = 2:4, b = 2) + ) + dbDisconnect(con, shutdown = TRUE) +}) + +test_that("relational setdiff() order-enforcing", { + # Autogenerated + drv <- duckdb() + con <- dbConnect(drv) + experimental <- FALSE + df1 <- data.frame(a = 1:4, b = 2) + df2 <- data.frame(a = 2:5, b = 2) + + "setdiff" + df3 <- rel_set_diff2(df1, df2, con) + "arrange" + df4 <- rel_order2(df3, con, list(expr_reference("a"), expr_reference("b"))) + expect_identical( + df4, + data.frame(a = 1L, b = 2) + ) + dbDisconnect(con, shutdown = TRUE) +}) From a2e22df860526913f789a68fd0fbb1399c6bdb3a Mon Sep 17 00:00:00 2001 From: Antonov548 Date: Tue, 18 Feb 2025 18:23:27 +0100 Subject: [PATCH 51/69] add test for `rel_set_symdiff2` --- tests/testthat/test-rel_api2.R | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/tests/testthat/test-rel_api2.R b/tests/testthat/test-rel_api2.R index 9584bc63a..686b06468 100644 --- a/tests/testthat/test-rel_api2.R +++ b/tests/testthat/test-rel_api2.R @@ -1115,3 +1115,22 @@ test_that("relational setdiff() order-enforcing", { ) dbDisconnect(con, shutdown = TRUE) }) + +test_that("relational symdiff() order-enforcing", { + # Autogenerated + drv <- duckdb() + con <- dbConnect(drv) + experimental <- FALSE + df1 <- data.frame(a = 1:4, b = 2) + df2 <- data.frame(a = 2:5, b = 2) + + "symdiff" + df3 <- rel_set_symdiff2(df1, df2, con) + "arrange" + df4 <- rel_order2(df3, con, list(expr_reference("a"), expr_reference("b"))) + expect_identical( + df4, + data.frame(a = c(1L, 5L), b = 2) + ) + dbDisconnect(con, shutdown = TRUE) +}) From 41dddac850784802ccc5dbd3e0064371b9c91004 Mon Sep 17 00:00:00 2001 From: Antonov548 Date: Tue, 18 Feb 2025 18:27:16 +0100 Subject: [PATCH 52/69] update cpp11 generated code --- src/cpp11.cpp | 139 +++++++++++++++++++++++++++++--------------------- 1 file changed, 80 insertions(+), 59 deletions(-) diff --git a/src/cpp11.cpp b/src/cpp11.cpp index 044c2d808..f6f493448 100644 --- a/src/cpp11.cpp +++ b/src/cpp11.cpp @@ -526,7 +526,6 @@ extern "C" SEXP _duckdb_rapi_release(SEXP stmt) { return R_NilValue; END_CPP11 } - // statement.cpp cpp11::list rapi_prepare(duckdb::conn_eptr_t conn, std::string query, cpp11::environment env); extern "C" SEXP _duckdb_rapi_prepare(SEXP conn, SEXP query, SEXP env) { @@ -587,64 +586,86 @@ extern "C" SEXP _duckdb_rapi_load_rfuns(SEXP dual) { extern "C" { static const R_CallMethodDef CallEntries[] = { - {"_duckdb_rapi_adbc_init_func", (DL_FUNC) &_duckdb_rapi_adbc_init_func, 0}, - {"_duckdb_rapi_bind", (DL_FUNC) &_duckdb_rapi_bind, 4}, - {"_duckdb_rapi_connect", (DL_FUNC) &_duckdb_rapi_connect, 1}, - {"_duckdb_rapi_disconnect", (DL_FUNC) &_duckdb_rapi_disconnect, 1}, - {"_duckdb_rapi_execute", (DL_FUNC) &_duckdb_rapi_execute, 3}, - {"_duckdb_rapi_execute_arrow", (DL_FUNC) &_duckdb_rapi_execute_arrow, 2}, - {"_duckdb_rapi_expr_comparison", (DL_FUNC) &_duckdb_rapi_expr_comparison, 2}, - {"_duckdb_rapi_expr_constant", (DL_FUNC) &_duckdb_rapi_expr_constant, 1}, - {"_duckdb_rapi_expr_function", (DL_FUNC) &_duckdb_rapi_expr_function, 4}, - {"_duckdb_rapi_expr_reference", (DL_FUNC) &_duckdb_rapi_expr_reference, 1}, - {"_duckdb_rapi_expr_set_alias", (DL_FUNC) &_duckdb_rapi_expr_set_alias, 2}, - {"_duckdb_rapi_expr_tostring", (DL_FUNC) &_duckdb_rapi_expr_tostring, 1}, - {"_duckdb_rapi_expr_window", (DL_FUNC) &_duckdb_rapi_expr_window, 9}, - {"_duckdb_rapi_get_null_SEXP_ptr", (DL_FUNC) &_duckdb_rapi_get_null_SEXP_ptr, 0}, - {"_duckdb_rapi_is_locked", (DL_FUNC) &_duckdb_rapi_is_locked, 1}, - {"_duckdb_rapi_list_arrow", (DL_FUNC) &_duckdb_rapi_list_arrow, 1}, - {"_duckdb_rapi_load_rfuns", (DL_FUNC) &_duckdb_rapi_load_rfuns, 1}, - {"_duckdb_rapi_lock", (DL_FUNC) &_duckdb_rapi_lock, 1}, - {"_duckdb_rapi_prepare", (DL_FUNC) &_duckdb_rapi_prepare, 3}, - {"_duckdb_rapi_ptr_to_str", (DL_FUNC) &_duckdb_rapi_ptr_to_str, 1}, - {"_duckdb_rapi_record_batch", (DL_FUNC) &_duckdb_rapi_record_batch, 2}, - {"_duckdb_rapi_register_arrow", (DL_FUNC) &_duckdb_rapi_register_arrow, 4}, - {"_duckdb_rapi_register_df", (DL_FUNC) &_duckdb_rapi_register_df, 6}, - {"_duckdb_rapi_rel_aggregate", (DL_FUNC) &_duckdb_rapi_rel_aggregate, 3}, - {"_duckdb_rapi_rel_alias", (DL_FUNC) &_duckdb_rapi_rel_alias, 1}, - {"_duckdb_rapi_rel_distinct", (DL_FUNC) &_duckdb_rapi_rel_distinct, 1}, - {"_duckdb_rapi_rel_explain", (DL_FUNC) &_duckdb_rapi_rel_explain, 3}, - {"_duckdb_rapi_rel_filter", (DL_FUNC) &_duckdb_rapi_rel_filter, 2}, - {"_duckdb_rapi_rel_from_altrep_df", (DL_FUNC) &_duckdb_rapi_rel_from_altrep_df, 3}, - {"_duckdb_rapi_rel_from_df", (DL_FUNC) &_duckdb_rapi_rel_from_df, 3}, - {"_duckdb_rapi_rel_from_sql", (DL_FUNC) &_duckdb_rapi_rel_from_sql, 2}, - {"_duckdb_rapi_rel_from_table", (DL_FUNC) &_duckdb_rapi_rel_from_table, 3}, - {"_duckdb_rapi_rel_from_table_function", (DL_FUNC) &_duckdb_rapi_rel_from_table_function, 4}, - {"_duckdb_rapi_rel_insert", (DL_FUNC) &_duckdb_rapi_rel_insert, 3}, - {"_duckdb_rapi_rel_join", (DL_FUNC) &_duckdb_rapi_rel_join, 5}, - {"_duckdb_rapi_rel_limit", (DL_FUNC) &_duckdb_rapi_rel_limit, 2}, - {"_duckdb_rapi_rel_names", (DL_FUNC) &_duckdb_rapi_rel_names, 1}, - {"_duckdb_rapi_rel_order", (DL_FUNC) &_duckdb_rapi_rel_order, 3}, - {"_duckdb_rapi_rel_project", (DL_FUNC) &_duckdb_rapi_rel_project, 2}, - {"_duckdb_rapi_rel_set_alias", (DL_FUNC) &_duckdb_rapi_rel_set_alias, 2}, - {"_duckdb_rapi_rel_set_diff", (DL_FUNC) &_duckdb_rapi_rel_set_diff, 2}, - {"_duckdb_rapi_rel_set_intersect", (DL_FUNC) &_duckdb_rapi_rel_set_intersect, 2}, - {"_duckdb_rapi_rel_set_symdiff", (DL_FUNC) &_duckdb_rapi_rel_set_symdiff, 2}, - {"_duckdb_rapi_rel_sql", (DL_FUNC) &_duckdb_rapi_rel_sql, 2}, - {"_duckdb_rapi_rel_to_altrep", (DL_FUNC) &_duckdb_rapi_rel_to_altrep, 4}, - {"_duckdb_rapi_rel_to_csv", (DL_FUNC) &_duckdb_rapi_rel_to_csv, 3}, - {"_duckdb_rapi_rel_to_df", (DL_FUNC) &_duckdb_rapi_rel_to_df, 1}, - {"_duckdb_rapi_rel_to_parquet", (DL_FUNC) &_duckdb_rapi_rel_to_parquet, 3}, - {"_duckdb_rapi_rel_to_sql", (DL_FUNC) &_duckdb_rapi_rel_to_sql, 1}, - {"_duckdb_rapi_rel_to_table", (DL_FUNC) &_duckdb_rapi_rel_to_table, 4}, - {"_duckdb_rapi_rel_tostring", (DL_FUNC) &_duckdb_rapi_rel_tostring, 2}, - {"_duckdb_rapi_rel_union_all", (DL_FUNC) &_duckdb_rapi_rel_union_all, 2}, - {"_duckdb_rapi_release", (DL_FUNC) &_duckdb_rapi_release, 1}, - {"_duckdb_rapi_shutdown", (DL_FUNC) &_duckdb_rapi_shutdown, 1}, - {"_duckdb_rapi_startup", (DL_FUNC) &_duckdb_rapi_startup, 4}, - {"_duckdb_rapi_unlock", (DL_FUNC) &_duckdb_rapi_unlock, 1}, - {"_duckdb_rapi_unregister_arrow", (DL_FUNC) &_duckdb_rapi_unregister_arrow, 2}, - {"_duckdb_rapi_unregister_df", (DL_FUNC) &_duckdb_rapi_unregister_df, 2}, + {"_duckdb_rapi_adbc_init_func", (DL_FUNC) &_duckdb_rapi_adbc_init_func, 0}, + {"_duckdb_rapi_bind", (DL_FUNC) &_duckdb_rapi_bind, 4}, + {"_duckdb_rapi_connect", (DL_FUNC) &_duckdb_rapi_connect, 1}, + {"_duckdb_rapi_disconnect", (DL_FUNC) &_duckdb_rapi_disconnect, 1}, + {"_duckdb_rapi_execute", (DL_FUNC) &_duckdb_rapi_execute, 3}, + {"_duckdb_rapi_execute_arrow", (DL_FUNC) &_duckdb_rapi_execute_arrow, 2}, + {"_duckdb_rapi_expr_comparison", (DL_FUNC) &_duckdb_rapi_expr_comparison, 2}, + {"_duckdb_rapi_expr_constant", (DL_FUNC) &_duckdb_rapi_expr_constant, 1}, + {"_duckdb_rapi_expr_function", (DL_FUNC) &_duckdb_rapi_expr_function, 4}, + {"_duckdb_rapi_expr_reference", (DL_FUNC) &_duckdb_rapi_expr_reference, 1}, + {"_duckdb_rapi_expr_set_alias", (DL_FUNC) &_duckdb_rapi_expr_set_alias, 2}, + {"_duckdb_rapi_expr_tostring", (DL_FUNC) &_duckdb_rapi_expr_tostring, 1}, + {"_duckdb_rapi_expr_window", (DL_FUNC) &_duckdb_rapi_expr_window, 9}, + {"_duckdb_rapi_get_null_SEXP_ptr", (DL_FUNC) &_duckdb_rapi_get_null_SEXP_ptr, 0}, + {"_duckdb_rapi_is_locked", (DL_FUNC) &_duckdb_rapi_is_locked, 1}, + {"_duckdb_rapi_list_arrow", (DL_FUNC) &_duckdb_rapi_list_arrow, 1}, + {"_duckdb_rapi_load_rfuns", (DL_FUNC) &_duckdb_rapi_load_rfuns, 1}, + {"_duckdb_rapi_lock", (DL_FUNC) &_duckdb_rapi_lock, 1}, + {"_duckdb_rapi_prepare", (DL_FUNC) &_duckdb_rapi_prepare, 3}, + {"_duckdb_rapi_ptr_to_str", (DL_FUNC) &_duckdb_rapi_ptr_to_str, 1}, + {"_duckdb_rapi_record_batch", (DL_FUNC) &_duckdb_rapi_record_batch, 2}, + {"_duckdb_rapi_register_arrow", (DL_FUNC) &_duckdb_rapi_register_arrow, 4}, + {"_duckdb_rapi_register_df", (DL_FUNC) &_duckdb_rapi_register_df, 6}, + {"_duckdb_rapi_rel_aggregate", (DL_FUNC) &_duckdb_rapi_rel_aggregate, 3}, + {"_duckdb_rapi_rel_aggregate2", (DL_FUNC) &_duckdb_rapi_rel_aggregate2, 4}, + {"_duckdb_rapi_rel_alias", (DL_FUNC) &_duckdb_rapi_rel_alias, 1}, + {"_duckdb_rapi_rel_alias2", (DL_FUNC) &_duckdb_rapi_rel_alias2, 2}, + {"_duckdb_rapi_rel_distinct", (DL_FUNC) &_duckdb_rapi_rel_distinct, 1}, + {"_duckdb_rapi_rel_distinct2", (DL_FUNC) &_duckdb_rapi_rel_distinct2, 2}, + {"_duckdb_rapi_rel_explain", (DL_FUNC) &_duckdb_rapi_rel_explain, 3}, + {"_duckdb_rapi_rel_explain2", (DL_FUNC) &_duckdb_rapi_rel_explain2, 4}, + {"_duckdb_rapi_rel_filter", (DL_FUNC) &_duckdb_rapi_rel_filter, 2}, + {"_duckdb_rapi_rel_filter2", (DL_FUNC) &_duckdb_rapi_rel_filter2, 3}, + {"_duckdb_rapi_rel_from_altrep_df", (DL_FUNC) &_duckdb_rapi_rel_from_altrep_df, 3}, + {"_duckdb_rapi_rel_from_df", (DL_FUNC) &_duckdb_rapi_rel_from_df, 3}, + {"_duckdb_rapi_rel_from_sql", (DL_FUNC) &_duckdb_rapi_rel_from_sql, 2}, + {"_duckdb_rapi_rel_from_sql2", (DL_FUNC) &_duckdb_rapi_rel_from_sql2, 2}, + {"_duckdb_rapi_rel_from_table", (DL_FUNC) &_duckdb_rapi_rel_from_table, 3}, + {"_duckdb_rapi_rel_from_table2", (DL_FUNC) &_duckdb_rapi_rel_from_table2, 3}, + {"_duckdb_rapi_rel_from_table_function", (DL_FUNC) &_duckdb_rapi_rel_from_table_function, 4}, + {"_duckdb_rapi_rel_from_table_function2", (DL_FUNC) &_duckdb_rapi_rel_from_table_function2, 4}, + {"_duckdb_rapi_rel_insert", (DL_FUNC) &_duckdb_rapi_rel_insert, 3}, + {"_duckdb_rapi_rel_insert2", (DL_FUNC) &_duckdb_rapi_rel_insert2, 4}, + {"_duckdb_rapi_rel_join", (DL_FUNC) &_duckdb_rapi_rel_join, 5}, + {"_duckdb_rapi_rel_join2", (DL_FUNC) &_duckdb_rapi_rel_join2, 6}, + {"_duckdb_rapi_rel_limit", (DL_FUNC) &_duckdb_rapi_rel_limit, 2}, + {"_duckdb_rapi_rel_limit2", (DL_FUNC) &_duckdb_rapi_rel_limit2, 3}, + {"_duckdb_rapi_rel_names", (DL_FUNC) &_duckdb_rapi_rel_names, 1}, + {"_duckdb_rapi_rel_names2", (DL_FUNC) &_duckdb_rapi_rel_names2, 2}, + {"_duckdb_rapi_rel_order", (DL_FUNC) &_duckdb_rapi_rel_order, 3}, + {"_duckdb_rapi_rel_order2", (DL_FUNC) &_duckdb_rapi_rel_order2, 4}, + {"_duckdb_rapi_rel_project", (DL_FUNC) &_duckdb_rapi_rel_project, 2}, + {"_duckdb_rapi_rel_project2", (DL_FUNC) &_duckdb_rapi_rel_project2, 3}, + {"_duckdb_rapi_rel_set_alias", (DL_FUNC) &_duckdb_rapi_rel_set_alias, 2}, + {"_duckdb_rapi_rel_set_alias2", (DL_FUNC) &_duckdb_rapi_rel_set_alias2, 3}, + {"_duckdb_rapi_rel_set_diff", (DL_FUNC) &_duckdb_rapi_rel_set_diff, 2}, + {"_duckdb_rapi_rel_set_diff2", (DL_FUNC) &_duckdb_rapi_rel_set_diff2, 3}, + {"_duckdb_rapi_rel_set_intersect", (DL_FUNC) &_duckdb_rapi_rel_set_intersect, 2}, + {"_duckdb_rapi_rel_set_intersect2", (DL_FUNC) &_duckdb_rapi_rel_set_intersect2, 3}, + {"_duckdb_rapi_rel_set_symdiff", (DL_FUNC) &_duckdb_rapi_rel_set_symdiff, 2}, + {"_duckdb_rapi_rel_set_symdiff2", (DL_FUNC) &_duckdb_rapi_rel_set_symdiff2, 3}, + {"_duckdb_rapi_rel_sql", (DL_FUNC) &_duckdb_rapi_rel_sql, 2}, + {"_duckdb_rapi_rel_to_altrep", (DL_FUNC) &_duckdb_rapi_rel_to_altrep, 4}, + {"_duckdb_rapi_rel_to_csv", (DL_FUNC) &_duckdb_rapi_rel_to_csv, 3}, + {"_duckdb_rapi_rel_to_csv2", (DL_FUNC) &_duckdb_rapi_rel_to_csv2, 4}, + {"_duckdb_rapi_rel_to_df", (DL_FUNC) &_duckdb_rapi_rel_to_df, 1}, + {"_duckdb_rapi_rel_to_parquet", (DL_FUNC) &_duckdb_rapi_rel_to_parquet, 3}, + {"_duckdb_rapi_rel_to_parquet2", (DL_FUNC) &_duckdb_rapi_rel_to_parquet2, 4}, + {"_duckdb_rapi_rel_to_sql", (DL_FUNC) &_duckdb_rapi_rel_to_sql, 1}, + {"_duckdb_rapi_rel_to_table", (DL_FUNC) &_duckdb_rapi_rel_to_table, 4}, + {"_duckdb_rapi_rel_to_table2", (DL_FUNC) &_duckdb_rapi_rel_to_table2, 5}, + {"_duckdb_rapi_rel_tostring", (DL_FUNC) &_duckdb_rapi_rel_tostring, 2}, + {"_duckdb_rapi_rel_union_all", (DL_FUNC) &_duckdb_rapi_rel_union_all, 2}, + {"_duckdb_rapi_rel_union_all2", (DL_FUNC) &_duckdb_rapi_rel_union_all2, 3}, + {"_duckdb_rapi_release", (DL_FUNC) &_duckdb_rapi_release, 1}, + {"_duckdb_rapi_shutdown", (DL_FUNC) &_duckdb_rapi_shutdown, 1}, + {"_duckdb_rapi_startup", (DL_FUNC) &_duckdb_rapi_startup, 4}, + {"_duckdb_rapi_unlock", (DL_FUNC) &_duckdb_rapi_unlock, 1}, + {"_duckdb_rapi_unregister_arrow", (DL_FUNC) &_duckdb_rapi_unregister_arrow, 2}, + {"_duckdb_rapi_unregister_df", (DL_FUNC) &_duckdb_rapi_unregister_df, 2}, {NULL, NULL, 0} }; } From 4688dd549b9b39002695b29f694d749ad6a333be Mon Sep 17 00:00:00 2001 From: Antonov548 Date: Wed, 26 Feb 2025 15:55:49 +0100 Subject: [PATCH 53/69] fix: merge --- R/cpp11.R | 88 ++++++++++++++++++++++++++++ src/cpp11.cpp | 138 +++++++++++++++++++++++++------------------- src/reltoaltrep.cpp | 1 + 3 files changed, 169 insertions(+), 58 deletions(-) diff --git a/R/cpp11.R b/R/cpp11.R index 89ccecef2..e82b171be 100644 --- a/R/cpp11.R +++ b/R/cpp11.R @@ -188,6 +188,94 @@ rapi_rel_insert <- function(rel, schema_name, table_name) { invisible(.Call(`_duckdb_rapi_rel_insert`, rel, schema_name, table_name)) } +rapi_rel_names2 <- function(df, con) { + .Call(`_duckdb_rapi_rel_names2`, df, con) +} + +rapi_rel_alias2 <- function(df, con) { + .Call(`_duckdb_rapi_rel_alias2`, df, con) +} + +rapi_rel_set_alias2 <- function(df, con, alias) { + .Call(`_duckdb_rapi_rel_set_alias2`, df, con, alias) +} + +rapi_rel_filter2 <- function(df, con, exprs) { + .Call(`_duckdb_rapi_rel_filter2`, df, con, exprs) +} + +rapi_rel_project2 <- function(df, con, exprs) { + .Call(`_duckdb_rapi_rel_project2`, df, con, exprs) +} + +rapi_rel_aggregate2 <- function(df, con, groups, aggregates) { + .Call(`_duckdb_rapi_rel_aggregate2`, df, con, groups, aggregates) +} + +rapi_rel_order2 <- function(df, con, orders, ascending) { + .Call(`_duckdb_rapi_rel_order2`, df, con, orders, ascending) +} + +rapi_rel_join2 <- function(left, right, con, conds, join, join_ref_type) { + .Call(`_duckdb_rapi_rel_join2`, left, right, con, conds, join, join_ref_type) +} + +rapi_rel_union_all2 <- function(left, right, con) { + .Call(`_duckdb_rapi_rel_union_all2`, left, right, con) +} + +rapi_rel_limit2 <- function(df, con, n) { + .Call(`_duckdb_rapi_rel_limit2`, df, con, n) +} + +rapi_rel_distinct2 <- function(df, con) { + .Call(`_duckdb_rapi_rel_distinct2`, df, con) +} + +rapi_rel_set_intersect2 <- function(left, right, con) { + .Call(`_duckdb_rapi_rel_set_intersect2`, left, right, con) +} + +rapi_rel_set_diff2 <- function(left, right, con) { + .Call(`_duckdb_rapi_rel_set_diff2`, left, right, con) +} + +rapi_rel_set_symdiff2 <- function(left, right, con) { + .Call(`_duckdb_rapi_rel_set_symdiff2`, left, right, con) +} + +rapi_rel_from_sql2 <- function(con, sql) { + .Call(`_duckdb_rapi_rel_from_sql2`, con, sql) +} + +rapi_rel_from_table2 <- function(con, schema_name, table_name) { + .Call(`_duckdb_rapi_rel_from_table2`, con, schema_name, table_name) +} + +rapi_rel_from_table_function2 <- function(con, function_name, positional_parameters_sexps, named_parameters_sexps) { + .Call(`_duckdb_rapi_rel_from_table_function2`, con, function_name, positional_parameters_sexps, named_parameters_sexps) +} + +rapi_rel_explain2 <- function(df, con, type, format) { + .Call(`_duckdb_rapi_rel_explain2`, df, con, type, format) +} + +rapi_rel_to_parquet2 <- function(df, con, file_name, options_sexps) { + invisible(.Call(`_duckdb_rapi_rel_to_parquet2`, df, con, file_name, options_sexps)) +} + +rapi_rel_to_csv2 <- function(df, con, file_name, options_sexps) { + invisible(.Call(`_duckdb_rapi_rel_to_csv2`, df, con, file_name, options_sexps)) +} + +rapi_rel_to_table2 <- function(df, con, schema_name, table_name, temporary) { + invisible(.Call(`_duckdb_rapi_rel_to_table2`, df, con, schema_name, table_name, temporary)) +} + +rapi_rel_insert2 <- function(df, con, schema_name, table_name) { + invisible(.Call(`_duckdb_rapi_rel_insert2`, df, con, schema_name, table_name)) +} + rapi_rel_to_altrep <- function(rel, n_rows, n_cells) { .Call(`_duckdb_rapi_rel_to_altrep`, rel, n_rows, n_cells) } diff --git a/src/cpp11.cpp b/src/cpp11.cpp index 4155fec62..0a3854290 100644 --- a/src/cpp11.cpp +++ b/src/cpp11.cpp @@ -586,64 +586,86 @@ extern "C" SEXP _duckdb_rapi_load_rfuns(SEXP dual) { extern "C" { static const R_CallMethodDef CallEntries[] = { - {"_duckdb_rapi_adbc_init_func", (DL_FUNC) &_duckdb_rapi_adbc_init_func, 0}, - {"_duckdb_rapi_bind", (DL_FUNC) &_duckdb_rapi_bind, 4}, - {"_duckdb_rapi_connect", (DL_FUNC) &_duckdb_rapi_connect, 1}, - {"_duckdb_rapi_disconnect", (DL_FUNC) &_duckdb_rapi_disconnect, 1}, - {"_duckdb_rapi_execute", (DL_FUNC) &_duckdb_rapi_execute, 3}, - {"_duckdb_rapi_execute_arrow", (DL_FUNC) &_duckdb_rapi_execute_arrow, 2}, - {"_duckdb_rapi_expr_comparison", (DL_FUNC) &_duckdb_rapi_expr_comparison, 2}, - {"_duckdb_rapi_expr_constant", (DL_FUNC) &_duckdb_rapi_expr_constant, 1}, - {"_duckdb_rapi_expr_function", (DL_FUNC) &_duckdb_rapi_expr_function, 4}, - {"_duckdb_rapi_expr_reference", (DL_FUNC) &_duckdb_rapi_expr_reference, 1}, - {"_duckdb_rapi_expr_set_alias", (DL_FUNC) &_duckdb_rapi_expr_set_alias, 2}, - {"_duckdb_rapi_expr_tostring", (DL_FUNC) &_duckdb_rapi_expr_tostring, 1}, - {"_duckdb_rapi_expr_window", (DL_FUNC) &_duckdb_rapi_expr_window, 9}, - {"_duckdb_rapi_get_null_SEXP_ptr", (DL_FUNC) &_duckdb_rapi_get_null_SEXP_ptr, 0}, - {"_duckdb_rapi_is_locked", (DL_FUNC) &_duckdb_rapi_is_locked, 1}, - {"_duckdb_rapi_list_arrow", (DL_FUNC) &_duckdb_rapi_list_arrow, 1}, - {"_duckdb_rapi_load_rfuns", (DL_FUNC) &_duckdb_rapi_load_rfuns, 1}, - {"_duckdb_rapi_lock", (DL_FUNC) &_duckdb_rapi_lock, 1}, - {"_duckdb_rapi_prepare", (DL_FUNC) &_duckdb_rapi_prepare, 3}, - {"_duckdb_rapi_ptr_to_str", (DL_FUNC) &_duckdb_rapi_ptr_to_str, 1}, - {"_duckdb_rapi_record_batch", (DL_FUNC) &_duckdb_rapi_record_batch, 2}, - {"_duckdb_rapi_register_arrow", (DL_FUNC) &_duckdb_rapi_register_arrow, 4}, - {"_duckdb_rapi_register_df", (DL_FUNC) &_duckdb_rapi_register_df, 6}, - {"_duckdb_rapi_rel_aggregate", (DL_FUNC) &_duckdb_rapi_rel_aggregate, 3}, - {"_duckdb_rapi_rel_alias", (DL_FUNC) &_duckdb_rapi_rel_alias, 1}, - {"_duckdb_rapi_rel_distinct", (DL_FUNC) &_duckdb_rapi_rel_distinct, 1}, - {"_duckdb_rapi_rel_explain", (DL_FUNC) &_duckdb_rapi_rel_explain, 3}, - {"_duckdb_rapi_rel_filter", (DL_FUNC) &_duckdb_rapi_rel_filter, 2}, - {"_duckdb_rapi_rel_from_altrep_df", (DL_FUNC) &_duckdb_rapi_rel_from_altrep_df, 3}, - {"_duckdb_rapi_rel_from_df", (DL_FUNC) &_duckdb_rapi_rel_from_df, 3}, - {"_duckdb_rapi_rel_from_sql", (DL_FUNC) &_duckdb_rapi_rel_from_sql, 2}, - {"_duckdb_rapi_rel_from_table", (DL_FUNC) &_duckdb_rapi_rel_from_table, 3}, - {"_duckdb_rapi_rel_from_table_function", (DL_FUNC) &_duckdb_rapi_rel_from_table_function, 4}, - {"_duckdb_rapi_rel_insert", (DL_FUNC) &_duckdb_rapi_rel_insert, 3}, - {"_duckdb_rapi_rel_join", (DL_FUNC) &_duckdb_rapi_rel_join, 5}, - {"_duckdb_rapi_rel_limit", (DL_FUNC) &_duckdb_rapi_rel_limit, 2}, - {"_duckdb_rapi_rel_names", (DL_FUNC) &_duckdb_rapi_rel_names, 1}, - {"_duckdb_rapi_rel_order", (DL_FUNC) &_duckdb_rapi_rel_order, 3}, - {"_duckdb_rapi_rel_project", (DL_FUNC) &_duckdb_rapi_rel_project, 2}, - {"_duckdb_rapi_rel_set_alias", (DL_FUNC) &_duckdb_rapi_rel_set_alias, 2}, - {"_duckdb_rapi_rel_set_diff", (DL_FUNC) &_duckdb_rapi_rel_set_diff, 2}, - {"_duckdb_rapi_rel_set_intersect", (DL_FUNC) &_duckdb_rapi_rel_set_intersect, 2}, - {"_duckdb_rapi_rel_set_symdiff", (DL_FUNC) &_duckdb_rapi_rel_set_symdiff, 2}, - {"_duckdb_rapi_rel_sql", (DL_FUNC) &_duckdb_rapi_rel_sql, 2}, - {"_duckdb_rapi_rel_to_altrep", (DL_FUNC) &_duckdb_rapi_rel_to_altrep, 3}, - {"_duckdb_rapi_rel_to_csv", (DL_FUNC) &_duckdb_rapi_rel_to_csv, 3}, - {"_duckdb_rapi_rel_to_df", (DL_FUNC) &_duckdb_rapi_rel_to_df, 1}, - {"_duckdb_rapi_rel_to_parquet", (DL_FUNC) &_duckdb_rapi_rel_to_parquet, 3}, - {"_duckdb_rapi_rel_to_sql", (DL_FUNC) &_duckdb_rapi_rel_to_sql, 1}, - {"_duckdb_rapi_rel_to_table", (DL_FUNC) &_duckdb_rapi_rel_to_table, 4}, - {"_duckdb_rapi_rel_tostring", (DL_FUNC) &_duckdb_rapi_rel_tostring, 2}, - {"_duckdb_rapi_rel_union_all", (DL_FUNC) &_duckdb_rapi_rel_union_all, 2}, - {"_duckdb_rapi_release", (DL_FUNC) &_duckdb_rapi_release, 1}, - {"_duckdb_rapi_shutdown", (DL_FUNC) &_duckdb_rapi_shutdown, 1}, - {"_duckdb_rapi_startup", (DL_FUNC) &_duckdb_rapi_startup, 4}, - {"_duckdb_rapi_unlock", (DL_FUNC) &_duckdb_rapi_unlock, 1}, - {"_duckdb_rapi_unregister_arrow", (DL_FUNC) &_duckdb_rapi_unregister_arrow, 2}, - {"_duckdb_rapi_unregister_df", (DL_FUNC) &_duckdb_rapi_unregister_df, 2}, + {"_duckdb_rapi_adbc_init_func", (DL_FUNC) &_duckdb_rapi_adbc_init_func, 0}, + {"_duckdb_rapi_bind", (DL_FUNC) &_duckdb_rapi_bind, 4}, + {"_duckdb_rapi_connect", (DL_FUNC) &_duckdb_rapi_connect, 1}, + {"_duckdb_rapi_disconnect", (DL_FUNC) &_duckdb_rapi_disconnect, 1}, + {"_duckdb_rapi_execute", (DL_FUNC) &_duckdb_rapi_execute, 3}, + {"_duckdb_rapi_execute_arrow", (DL_FUNC) &_duckdb_rapi_execute_arrow, 2}, + {"_duckdb_rapi_expr_comparison", (DL_FUNC) &_duckdb_rapi_expr_comparison, 2}, + {"_duckdb_rapi_expr_constant", (DL_FUNC) &_duckdb_rapi_expr_constant, 1}, + {"_duckdb_rapi_expr_function", (DL_FUNC) &_duckdb_rapi_expr_function, 4}, + {"_duckdb_rapi_expr_reference", (DL_FUNC) &_duckdb_rapi_expr_reference, 1}, + {"_duckdb_rapi_expr_set_alias", (DL_FUNC) &_duckdb_rapi_expr_set_alias, 2}, + {"_duckdb_rapi_expr_tostring", (DL_FUNC) &_duckdb_rapi_expr_tostring, 1}, + {"_duckdb_rapi_expr_window", (DL_FUNC) &_duckdb_rapi_expr_window, 9}, + {"_duckdb_rapi_get_null_SEXP_ptr", (DL_FUNC) &_duckdb_rapi_get_null_SEXP_ptr, 0}, + {"_duckdb_rapi_is_locked", (DL_FUNC) &_duckdb_rapi_is_locked, 1}, + {"_duckdb_rapi_list_arrow", (DL_FUNC) &_duckdb_rapi_list_arrow, 1}, + {"_duckdb_rapi_load_rfuns", (DL_FUNC) &_duckdb_rapi_load_rfuns, 1}, + {"_duckdb_rapi_lock", (DL_FUNC) &_duckdb_rapi_lock, 1}, + {"_duckdb_rapi_prepare", (DL_FUNC) &_duckdb_rapi_prepare, 3}, + {"_duckdb_rapi_ptr_to_str", (DL_FUNC) &_duckdb_rapi_ptr_to_str, 1}, + {"_duckdb_rapi_record_batch", (DL_FUNC) &_duckdb_rapi_record_batch, 2}, + {"_duckdb_rapi_register_arrow", (DL_FUNC) &_duckdb_rapi_register_arrow, 4}, + {"_duckdb_rapi_register_df", (DL_FUNC) &_duckdb_rapi_register_df, 6}, + {"_duckdb_rapi_rel_aggregate", (DL_FUNC) &_duckdb_rapi_rel_aggregate, 3}, + {"_duckdb_rapi_rel_aggregate2", (DL_FUNC) &_duckdb_rapi_rel_aggregate2, 4}, + {"_duckdb_rapi_rel_alias", (DL_FUNC) &_duckdb_rapi_rel_alias, 1}, + {"_duckdb_rapi_rel_alias2", (DL_FUNC) &_duckdb_rapi_rel_alias2, 2}, + {"_duckdb_rapi_rel_distinct", (DL_FUNC) &_duckdb_rapi_rel_distinct, 1}, + {"_duckdb_rapi_rel_distinct2", (DL_FUNC) &_duckdb_rapi_rel_distinct2, 2}, + {"_duckdb_rapi_rel_explain", (DL_FUNC) &_duckdb_rapi_rel_explain, 3}, + {"_duckdb_rapi_rel_explain2", (DL_FUNC) &_duckdb_rapi_rel_explain2, 4}, + {"_duckdb_rapi_rel_filter", (DL_FUNC) &_duckdb_rapi_rel_filter, 2}, + {"_duckdb_rapi_rel_filter2", (DL_FUNC) &_duckdb_rapi_rel_filter2, 3}, + {"_duckdb_rapi_rel_from_altrep_df", (DL_FUNC) &_duckdb_rapi_rel_from_altrep_df, 3}, + {"_duckdb_rapi_rel_from_df", (DL_FUNC) &_duckdb_rapi_rel_from_df, 3}, + {"_duckdb_rapi_rel_from_sql", (DL_FUNC) &_duckdb_rapi_rel_from_sql, 2}, + {"_duckdb_rapi_rel_from_sql2", (DL_FUNC) &_duckdb_rapi_rel_from_sql2, 2}, + {"_duckdb_rapi_rel_from_table", (DL_FUNC) &_duckdb_rapi_rel_from_table, 3}, + {"_duckdb_rapi_rel_from_table2", (DL_FUNC) &_duckdb_rapi_rel_from_table2, 3}, + {"_duckdb_rapi_rel_from_table_function", (DL_FUNC) &_duckdb_rapi_rel_from_table_function, 4}, + {"_duckdb_rapi_rel_from_table_function2", (DL_FUNC) &_duckdb_rapi_rel_from_table_function2, 4}, + {"_duckdb_rapi_rel_insert", (DL_FUNC) &_duckdb_rapi_rel_insert, 3}, + {"_duckdb_rapi_rel_insert2", (DL_FUNC) &_duckdb_rapi_rel_insert2, 4}, + {"_duckdb_rapi_rel_join", (DL_FUNC) &_duckdb_rapi_rel_join, 5}, + {"_duckdb_rapi_rel_join2", (DL_FUNC) &_duckdb_rapi_rel_join2, 6}, + {"_duckdb_rapi_rel_limit", (DL_FUNC) &_duckdb_rapi_rel_limit, 2}, + {"_duckdb_rapi_rel_limit2", (DL_FUNC) &_duckdb_rapi_rel_limit2, 3}, + {"_duckdb_rapi_rel_names", (DL_FUNC) &_duckdb_rapi_rel_names, 1}, + {"_duckdb_rapi_rel_names2", (DL_FUNC) &_duckdb_rapi_rel_names2, 2}, + {"_duckdb_rapi_rel_order", (DL_FUNC) &_duckdb_rapi_rel_order, 3}, + {"_duckdb_rapi_rel_order2", (DL_FUNC) &_duckdb_rapi_rel_order2, 4}, + {"_duckdb_rapi_rel_project", (DL_FUNC) &_duckdb_rapi_rel_project, 2}, + {"_duckdb_rapi_rel_project2", (DL_FUNC) &_duckdb_rapi_rel_project2, 3}, + {"_duckdb_rapi_rel_set_alias", (DL_FUNC) &_duckdb_rapi_rel_set_alias, 2}, + {"_duckdb_rapi_rel_set_alias2", (DL_FUNC) &_duckdb_rapi_rel_set_alias2, 3}, + {"_duckdb_rapi_rel_set_diff", (DL_FUNC) &_duckdb_rapi_rel_set_diff, 2}, + {"_duckdb_rapi_rel_set_diff2", (DL_FUNC) &_duckdb_rapi_rel_set_diff2, 3}, + {"_duckdb_rapi_rel_set_intersect", (DL_FUNC) &_duckdb_rapi_rel_set_intersect, 2}, + {"_duckdb_rapi_rel_set_intersect2", (DL_FUNC) &_duckdb_rapi_rel_set_intersect2, 3}, + {"_duckdb_rapi_rel_set_symdiff", (DL_FUNC) &_duckdb_rapi_rel_set_symdiff, 2}, + {"_duckdb_rapi_rel_set_symdiff2", (DL_FUNC) &_duckdb_rapi_rel_set_symdiff2, 3}, + {"_duckdb_rapi_rel_sql", (DL_FUNC) &_duckdb_rapi_rel_sql, 2}, + {"_duckdb_rapi_rel_to_altrep", (DL_FUNC) &_duckdb_rapi_rel_to_altrep, 3}, + {"_duckdb_rapi_rel_to_csv", (DL_FUNC) &_duckdb_rapi_rel_to_csv, 3}, + {"_duckdb_rapi_rel_to_csv2", (DL_FUNC) &_duckdb_rapi_rel_to_csv2, 4}, + {"_duckdb_rapi_rel_to_df", (DL_FUNC) &_duckdb_rapi_rel_to_df, 1}, + {"_duckdb_rapi_rel_to_parquet", (DL_FUNC) &_duckdb_rapi_rel_to_parquet, 3}, + {"_duckdb_rapi_rel_to_parquet2", (DL_FUNC) &_duckdb_rapi_rel_to_parquet2, 4}, + {"_duckdb_rapi_rel_to_sql", (DL_FUNC) &_duckdb_rapi_rel_to_sql, 1}, + {"_duckdb_rapi_rel_to_table", (DL_FUNC) &_duckdb_rapi_rel_to_table, 4}, + {"_duckdb_rapi_rel_to_table2", (DL_FUNC) &_duckdb_rapi_rel_to_table2, 5}, + {"_duckdb_rapi_rel_tostring", (DL_FUNC) &_duckdb_rapi_rel_tostring, 2}, + {"_duckdb_rapi_rel_union_all", (DL_FUNC) &_duckdb_rapi_rel_union_all, 2}, + {"_duckdb_rapi_rel_union_all2", (DL_FUNC) &_duckdb_rapi_rel_union_all2, 3}, + {"_duckdb_rapi_release", (DL_FUNC) &_duckdb_rapi_release, 1}, + {"_duckdb_rapi_shutdown", (DL_FUNC) &_duckdb_rapi_shutdown, 1}, + {"_duckdb_rapi_startup", (DL_FUNC) &_duckdb_rapi_startup, 4}, + {"_duckdb_rapi_unlock", (DL_FUNC) &_duckdb_rapi_unlock, 1}, + {"_duckdb_rapi_unregister_arrow", (DL_FUNC) &_duckdb_rapi_unregister_arrow, 2}, + {"_duckdb_rapi_unregister_df", (DL_FUNC) &_duckdb_rapi_unregister_df, 2}, {NULL, NULL, 0} }; } diff --git a/src/reltoaltrep.cpp b/src/reltoaltrep.cpp index a53cd9b49..01eab8e34 100644 --- a/src/reltoaltrep.cpp +++ b/src/reltoaltrep.cpp @@ -408,6 +408,7 @@ size_t DoubleToSize(double d) { // convert to SEXP (void)(SEXP)data_frame; + const auto allow_materialization = true; auto relation_wrapper = make_shared_ptr(rel, allow_materialization, DoubleToSize(n_rows), DoubleToSize(n_cells), data_frame); From 1690389d4351ff2c1ee2fc289be5b2f7836940e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Sat, 8 Mar 2025 11:57:21 +0100 Subject: [PATCH 54/69] Patch --- patch/0013-rel-ext.patch | 144 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 patch/0013-rel-ext.patch diff --git a/patch/0013-rel-ext.patch b/patch/0013-rel-ext.patch new file mode 100644 index 000000000..051e4be4a --- /dev/null +++ b/patch/0013-rel-ext.patch @@ -0,0 +1,144 @@ +diff --git a/src/duckdb/src/common/enum_util.cpp b/src/duckdb/src/common/enum_util.cpp +index 49e7bb2b9..8ab96b7da 100644 +--- a/src/duckdb/src/common/enum_util.cpp ++++ b/src/duckdb/src/common/enum_util.cpp +@@ -3157,19 +3157,20 @@ const StringUtil::EnumStringLiteral *GetRelationTypeValues() { + { static_cast(RelationType::VIEW_RELATION), "VIEW_RELATION" }, + { static_cast(RelationType::QUERY_RELATION), "QUERY_RELATION" }, + { static_cast(RelationType::DELIM_JOIN_RELATION), "DELIM_JOIN_RELATION" }, +- { static_cast(RelationType::DELIM_GET_RELATION), "DELIM_GET_RELATION" } ++ { static_cast(RelationType::DELIM_GET_RELATION), "DELIM_GET_RELATION" }, ++ { static_cast(RelationType::EXTENSION_RELATION), "EXTENSION_RELATION" } + }; + return values; + } + + template<> + const char* EnumUtil::ToChars(RelationType value) { +- return StringUtil::EnumToString(GetRelationTypeValues(), 28, "RelationType", static_cast(value)); ++ return StringUtil::EnumToString(GetRelationTypeValues(), 29, "RelationType", static_cast(value)); + } + + template<> + RelationType EnumUtil::FromString(const char *value) { +- return static_cast(StringUtil::StringToEnum(GetRelationTypeValues(), 28, "RelationType", value)); ++ return static_cast(StringUtil::StringToEnum(GetRelationTypeValues(), 29, "RelationType", value)); + } + + const StringUtil::EnumStringLiteral *GetRenderModeValues() { +diff --git a/src/duckdb/src/common/enums/relation_type.cpp b/src/duckdb/src/common/enums/relation_type.cpp +index 4f58ed7c4..dc02b8970 100644 +--- a/src/duckdb/src/common/enums/relation_type.cpp ++++ b/src/duckdb/src/common/enums/relation_type.cpp +@@ -61,6 +61,8 @@ string RelationTypeToString(RelationType type) { + return "VIEW_RELATION"; + case RelationType::QUERY_RELATION: + return "QUERY_RELATION"; ++ case RelationType::EXTENSION_RELATION: ++ return "EXTENSION_RELATION"; + case RelationType::INVALID_RELATION: + break; + } +diff --git a/src/duckdb/src/include/duckdb/common/enums/relation_type.hpp b/src/duckdb/src/include/duckdb/common/enums/relation_type.hpp +index 302b2f369..bca6af491 100644 +--- a/src/duckdb/src/include/duckdb/common/enums/relation_type.hpp ++++ b/src/duckdb/src/include/duckdb/common/enums/relation_type.hpp +@@ -43,7 +43,8 @@ enum class RelationType : uint8_t { + VIEW_RELATION, + QUERY_RELATION, + DELIM_JOIN_RELATION, +- DELIM_GET_RELATION ++ DELIM_GET_RELATION, ++ EXTENSION_RELATION = 255 + }; + + string RelationTypeToString(RelationType type); +diff --git a/src/duckdb/src/include/duckdb/main/connection.hpp b/src/duckdb/src/include/duckdb/main/connection.hpp +index f5b46717c..a40042768 100644 +--- a/src/duckdb/src/include/duckdb/main/connection.hpp ++++ b/src/duckdb/src/include/duckdb/main/connection.hpp +@@ -139,10 +139,10 @@ public: + DUCKDB_API shared_ptr View(const string &tname); + DUCKDB_API shared_ptr View(const string &schema_name, const string &table_name); + //! Returns a relation that calls a specified table function +- DUCKDB_API shared_ptr TableFunction(const string &tname); ++ DUCKDB_API shared_ptr TableFunction(const string &tname, bool auto_init = true); + DUCKDB_API shared_ptr TableFunction(const string &tname, const vector &values, +- const named_parameter_map_t &named_parameters); +- DUCKDB_API shared_ptr TableFunction(const string &tname, const vector &values); ++ const named_parameter_map_t &named_parameters, bool auto_init = true); ++ DUCKDB_API shared_ptr TableFunction(const string &tname, const vector &values, bool auto_init = true); + //! Returns a relation that produces values + DUCKDB_API shared_ptr Values(const vector> &values); + DUCKDB_API shared_ptr Values(vector>> &&values); +diff --git a/src/duckdb/src/include/duckdb/main/relation.hpp b/src/duckdb/src/include/duckdb/main/relation.hpp +index 37b137aae..62ffeedb8 100644 +--- a/src/duckdb/src/include/duckdb/main/relation.hpp ++++ b/src/duckdb/src/include/duckdb/main/relation.hpp +@@ -197,9 +197,9 @@ public: + DUCKDB_API virtual void Delete(const string &condition = string()); + //! Create a relation from calling a table in/out function on the input relation + //! Create a relation from calling a table in/out function on the input relation +- DUCKDB_API shared_ptr TableFunction(const std::string &fname, const vector &values); ++ DUCKDB_API shared_ptr TableFunction(const std::string &fname, const vector &values, bool auto_init = true); + DUCKDB_API shared_ptr TableFunction(const std::string &fname, const vector &values, +- const named_parameter_map_t &named_parameters); ++ const named_parameter_map_t &named_parameters, bool auto_init = true); + + public: + //! Whether or not the relation inherits column bindings from its child or not, only relevant for binding +diff --git a/src/duckdb/src/main/connection.cpp b/src/duckdb/src/main/connection.cpp +index a5742dbfd..9c137581a 100644 +--- a/src/duckdb/src/main/connection.cpp ++++ b/src/duckdb/src/main/connection.cpp +@@ -217,19 +217,19 @@ shared_ptr Connection::View(const string &schema_name, const string &t + return make_shared_ptr(context, schema_name, table_name); + } + +-shared_ptr Connection::TableFunction(const string &fname) { +- vector values; +- named_parameter_map_t named_parameters; +- return TableFunction(fname, values, named_parameters); ++shared_ptr Connection::TableFunction(const string &fname, const vector &values, ++ const named_parameter_map_t &named_parameters, bool auto_init) { ++ return make_shared_ptr(context, fname, values, named_parameters, nullptr, auto_init); + } + +-shared_ptr Connection::TableFunction(const string &fname, const vector &values, +- const named_parameter_map_t &named_parameters) { +- return make_shared_ptr(context, fname, values, named_parameters); ++shared_ptr Connection::TableFunction(const string &fname, const vector &values, bool auto_init) { ++ return make_shared_ptr(context, fname, values, nullptr, auto_init); + } + +-shared_ptr Connection::TableFunction(const string &fname, const vector &values) { +- return make_shared_ptr(context, fname, values); ++shared_ptr Connection::TableFunction(const string &fname, bool auto_init) { ++ vector values; ++ named_parameter_map_t named_parameters; ++ return TableFunction(fname, values, named_parameters, auto_init); + } + + shared_ptr Connection::Values(const vector> &values) { +diff --git a/src/duckdb/src/main/relation.cpp b/src/duckdb/src/main/relation.cpp +index 9154822f9..3e65ce993 100644 +--- a/src/duckdb/src/main/relation.cpp ++++ b/src/duckdb/src/main/relation.cpp +@@ -369,13 +369,13 @@ void Relation::Delete(const string &condition) { + } + + shared_ptr Relation::TableFunction(const std::string &fname, const vector &values, +- const named_parameter_map_t &named_parameters) { ++ const named_parameter_map_t &named_parameters, bool auto_init) { + return make_shared_ptr(context->GetContext(), fname, values, named_parameters, +- shared_from_this()); ++ shared_from_this(), auto_init); + } + +-shared_ptr Relation::TableFunction(const std::string &fname, const vector &values) { +- return make_shared_ptr(context->GetContext(), fname, values, shared_from_this()); ++shared_ptr Relation::TableFunction(const std::string &fname, const vector &values, bool auto_init) { ++ return make_shared_ptr(context->GetContext(), fname, values, shared_from_this(), auto_init); + } + + string Relation::ToString() { From 47dc91684e02450a9a678c8aa0ba018906161270 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Sat, 8 Mar 2025 12:18:09 +0100 Subject: [PATCH 55/69] rel...2 -> reldf --- R/cpp11.R | 88 ++++----- R/relational.R | 101 +++++----- R/rethrow-gen.R | 132 ++++++------- src/cpp11.cpp | 292 ++++++++++++++-------------- src/include/reltoaltrep.hpp | 2 +- src/relational2.cpp | 78 ++++---- src/reltoaltrep.cpp | 4 +- test-old.R | 43 ---- test.R | 48 ----- tests/testthat/_snaps/relational.md | 12 +- tests/testthat/test-list.R | 2 +- tests/testthat/test-parquet.R | 6 +- tests/testthat/test-readonly.R | 2 +- tests/testthat/test-rel_api.R | 228 +++++++++++----------- tests/testthat/test-rel_api2.R | 118 +++++------ tests/testthat/test-relational.R | 196 +++++++++---------- 16 files changed, 633 insertions(+), 719 deletions(-) delete mode 100644 test-old.R delete mode 100644 test.R diff --git a/R/cpp11.R b/R/cpp11.R index e82b171be..baa5c02d3 100644 --- a/R/cpp11.R +++ b/R/cpp11.R @@ -188,92 +188,92 @@ rapi_rel_insert <- function(rel, schema_name, table_name) { invisible(.Call(`_duckdb_rapi_rel_insert`, rel, schema_name, table_name)) } -rapi_rel_names2 <- function(df, con) { - .Call(`_duckdb_rapi_rel_names2`, df, con) +rapi_reldf_names <- function(df, con) { + .Call(`_duckdb_rapi_reldf_names`, df, con) } -rapi_rel_alias2 <- function(df, con) { - .Call(`_duckdb_rapi_rel_alias2`, df, con) +rapi_reldf_alias <- function(df, con) { + .Call(`_duckdb_rapi_reldf_alias`, df, con) } -rapi_rel_set_alias2 <- function(df, con, alias) { - .Call(`_duckdb_rapi_rel_set_alias2`, df, con, alias) +rapi_reldf_set_alias <- function(df, con, alias) { + .Call(`_duckdb_rapi_reldf_set_alias`, df, con, alias) } -rapi_rel_filter2 <- function(df, con, exprs) { - .Call(`_duckdb_rapi_rel_filter2`, df, con, exprs) +rapi_reldf_filter <- function(df, con, exprs) { + .Call(`_duckdb_rapi_reldf_filter`, df, con, exprs) } -rapi_rel_project2 <- function(df, con, exprs) { - .Call(`_duckdb_rapi_rel_project2`, df, con, exprs) +rapi_reldf_project <- function(df, con, exprs) { + .Call(`_duckdb_rapi_reldf_project`, df, con, exprs) } -rapi_rel_aggregate2 <- function(df, con, groups, aggregates) { - .Call(`_duckdb_rapi_rel_aggregate2`, df, con, groups, aggregates) +rapi_reldf_aggregate <- function(df, con, groups, aggregates) { + .Call(`_duckdb_rapi_reldf_aggregate`, df, con, groups, aggregates) } -rapi_rel_order2 <- function(df, con, orders, ascending) { - .Call(`_duckdb_rapi_rel_order2`, df, con, orders, ascending) +rapi_reldf_order <- function(df, con, orders, ascending) { + .Call(`_duckdb_rapi_reldf_order`, df, con, orders, ascending) } -rapi_rel_join2 <- function(left, right, con, conds, join, join_ref_type) { - .Call(`_duckdb_rapi_rel_join2`, left, right, con, conds, join, join_ref_type) +rapi_reldf_join <- function(left, right, con, conds, join, join_ref_type) { + .Call(`_duckdb_rapi_reldf_join`, left, right, con, conds, join, join_ref_type) } -rapi_rel_union_all2 <- function(left, right, con) { - .Call(`_duckdb_rapi_rel_union_all2`, left, right, con) +rapi_reldf_union_all <- function(left, right, con) { + .Call(`_duckdb_rapi_reldf_union_all`, left, right, con) } -rapi_rel_limit2 <- function(df, con, n) { - .Call(`_duckdb_rapi_rel_limit2`, df, con, n) +rapi_reldf_limit <- function(df, con, n) { + .Call(`_duckdb_rapi_reldf_limit`, df, con, n) } -rapi_rel_distinct2 <- function(df, con) { - .Call(`_duckdb_rapi_rel_distinct2`, df, con) +rapi_reldf_distinct <- function(df, con) { + .Call(`_duckdb_rapi_reldf_distinct`, df, con) } -rapi_rel_set_intersect2 <- function(left, right, con) { - .Call(`_duckdb_rapi_rel_set_intersect2`, left, right, con) +rapi_reldf_set_intersect <- function(left, right, con) { + .Call(`_duckdb_rapi_reldf_set_intersect`, left, right, con) } -rapi_rel_set_diff2 <- function(left, right, con) { - .Call(`_duckdb_rapi_rel_set_diff2`, left, right, con) +rapi_reldf_set_diff <- function(left, right, con) { + .Call(`_duckdb_rapi_reldf_set_diff`, left, right, con) } -rapi_rel_set_symdiff2 <- function(left, right, con) { - .Call(`_duckdb_rapi_rel_set_symdiff2`, left, right, con) +rapi_reldf_set_symdiff <- function(left, right, con) { + .Call(`_duckdb_rapi_reldf_set_symdiff`, left, right, con) } -rapi_rel_from_sql2 <- function(con, sql) { - .Call(`_duckdb_rapi_rel_from_sql2`, con, sql) +rapi_reldf_from_sql <- function(con, sql) { + .Call(`_duckdb_rapi_reldf_from_sql`, con, sql) } -rapi_rel_from_table2 <- function(con, schema_name, table_name) { - .Call(`_duckdb_rapi_rel_from_table2`, con, schema_name, table_name) +rapi_reldf_from_table <- function(con, schema_name, table_name) { + .Call(`_duckdb_rapi_reldf_from_table`, con, schema_name, table_name) } -rapi_rel_from_table_function2 <- function(con, function_name, positional_parameters_sexps, named_parameters_sexps) { - .Call(`_duckdb_rapi_rel_from_table_function2`, con, function_name, positional_parameters_sexps, named_parameters_sexps) +rapi_reldf_from_table_function <- function(con, function_name, positional_parameters_sexps, named_parameters_sexps) { + .Call(`_duckdb_rapi_reldf_from_table_function`, con, function_name, positional_parameters_sexps, named_parameters_sexps) } -rapi_rel_explain2 <- function(df, con, type, format) { - .Call(`_duckdb_rapi_rel_explain2`, df, con, type, format) +rapi_reldf_explain <- function(df, con, type, format) { + .Call(`_duckdb_rapi_reldf_explain`, df, con, type, format) } -rapi_rel_to_parquet2 <- function(df, con, file_name, options_sexps) { - invisible(.Call(`_duckdb_rapi_rel_to_parquet2`, df, con, file_name, options_sexps)) +rapi_reldf_to_parquet <- function(df, con, file_name, options_sexps) { + invisible(.Call(`_duckdb_rapi_reldf_to_parquet`, df, con, file_name, options_sexps)) } -rapi_rel_to_csv2 <- function(df, con, file_name, options_sexps) { - invisible(.Call(`_duckdb_rapi_rel_to_csv2`, df, con, file_name, options_sexps)) +rapi_reldf_to_csv <- function(df, con, file_name, options_sexps) { + invisible(.Call(`_duckdb_rapi_reldf_to_csv`, df, con, file_name, options_sexps)) } -rapi_rel_to_table2 <- function(df, con, schema_name, table_name, temporary) { - invisible(.Call(`_duckdb_rapi_rel_to_table2`, df, con, schema_name, table_name, temporary)) +rapi_reldf_to_table <- function(df, con, schema_name, table_name, temporary) { + invisible(.Call(`_duckdb_rapi_reldf_to_table`, df, con, schema_name, table_name, temporary)) } -rapi_rel_insert2 <- function(df, con, schema_name, table_name) { - invisible(.Call(`_duckdb_rapi_rel_insert2`, df, con, schema_name, table_name)) +rapi_reldf_insert <- function(df, con, schema_name, table_name) { + invisible(.Call(`_duckdb_rapi_reldf_insert`, df, con, schema_name, table_name)) } rapi_rel_to_altrep <- function(rel, n_rows, n_cells) { diff --git a/R/relational.R b/R/relational.R index df96f2f80..4d5d72508 100644 --- a/R/relational.R +++ b/R/relational.R @@ -29,7 +29,7 @@ expr_reference <- function(names, table = NULL) { #' col_ref_expr2 <- expr_reference("some_column_name", "some_table_name") expr_reference2 <- function(names, table = NULL, con = NULL) { if (inherits(table, "data.frame")) { - names <- c(rel_alias2(table, con), names) + names <- c(reldf_alias(table, con), names) } if (is.character(table) && !identical(table, "")) { names <- c(table, names) @@ -148,8 +148,8 @@ rel_limit <- function(rel, n) { #' con <- DBI::dbConnect(duckdb()) #' rel <- rel_from_df(con, mtcars) #' rel2 <- rel_limit(rel, 10) -rel_limit2 <- function(df, con, n) { - rethrow_rapi_rel_limit2(df, con@conn_ref, n) +reldf_limit <- function(df, con, n) { + rethrow_rapi_reldf_limit(df, con@conn_ref, n) } #' Lazily project a DuckDB relation object @@ -174,8 +174,8 @@ rel_project <- function(rel, exprs) { #' con <- DBI::dbConnect(duckdb()) #' rel <- rel_from_df(con, mtcars) #' rel2 <- rel_project(rel, list(expr_reference("cyl"), expr_reference("disp"))) -rel_project2 <- function(df, con, exprs) { - rethrow_rapi_rel_project2(df, con@conn_ref, exprs) +reldf_project <- function(df, con, exprs) { + rethrow_rapi_reldf_project(df, con@conn_ref, exprs) } #' Lazily filter a DuckDB relation object @@ -202,8 +202,8 @@ rel_filter <- function(rel, exprs) { #' DBI::dbExecute(con, "CREATE OR REPLACE MACRO gt(a, b) AS a > b") #' rel <- rel_from_df(con, mtcars) #' rel2 <- rel_filter(rel, list(expr_function("gt", list(expr_reference("cyl"), expr_constant("6"))))) -rel_filter2 <- function(df, con, exprs) { - rethrow_rapi_rel_filter2(df, con@conn_ref, exprs) +reldf_filter <- function(df, con, exprs) { + rethrow_rapi_reldf_filter(df, con@conn_ref, exprs) } #' Lazily aggregate a DuckDB relation object @@ -232,8 +232,8 @@ rel_aggregate <- function(rel, groups, aggregates) { #' rel <- rel_from_df(con, mtcars) #' aggrs <- list(avg_hp = expr_function("avg", list(expr_reference("hp")))) #' rel2 <- rel_aggregate(rel, list(expr_reference("cyl")), aggrs) -rel_aggregate2 <- function(df, con, groups, aggregates) { - rethrow_rapi_rel_aggregate2(df, con@conn_ref, groups, aggregates) +reldf_aggregate <- function(df, con, groups, aggregates) { + rethrow_rapi_reldf_aggregate(df, con@conn_ref, groups, aggregates) } #' Lazily reorder a DuckDB relation object @@ -268,7 +268,7 @@ rel_order <- function(rel, orders, ascending = NULL) { #' con <- DBI::dbConnect(duckdb()) #' rel <- rel_from_df(con, mtcars) #' rel2 <- rel_order(rel, list(expr_reference("hp"))) -rel_order2 <- function(df, con, orders, ascending = NULL) { +reldf_order <- function(df, con, orders, ascending = NULL) { if (is.null(ascending)) { ascending <- rep(TRUE, length(orders)) } @@ -277,7 +277,7 @@ rel_order2 <- function(df, con, orders, ascending = NULL) { stop("length of ascending must equal length of orders") } - return(rethrow_rapi_rel_order2(df, con@conn_ref, orders, ascending)) + return(rethrow_rapi_reldf_order(df, con@conn_ref, orders, ascending)) } #' Get an external pointer pointing to NULL @@ -357,9 +357,14 @@ rel_join <- function(left, right, conds, rethrow_rapi_rel_join(left, right, conds, join, join_ref_type) } -rel_join2 <- function(left, right, con, conds, - join = c("inner", "left", "right", "outer", "cross", "semi", "anti"), - join_ref_type = c("regular", "natural", "cross", "positional", "asof")) { +reldf_join <- function( + left, + right, + con, + conds, + join = c("inner", "left", "right", "outer", "cross", "semi", "anti"), + join_ref_type = c("regular", "natural", "cross", "positional", "asof") +) { join <- match.arg(join) join_ref_type <- match.arg(join_ref_type) # the ref type is naturally regular. Users won't write rel_join(left, right, conds, "cross", "cross") @@ -367,7 +372,7 @@ rel_join2 <- function(left, right, con, conds, if (join == "cross" && join_ref_type == "regular") { join_ref_type <- "cross" } - rethrow_rapi_rel_join2(left, right, con@conn_ref, conds, join, join_ref_type) + rethrow_rapi_reldf_join(left, right, con@conn_ref, conds, join, join_ref_type) } #' UNION ALL on two DuckDB relation objects @@ -394,8 +399,8 @@ rel_union_all <- function(rel_a, rel_b) { #' rel_a <- rel_from_df(con, mtcars) #' rel_b <- rel_from_df(con, mtcars) #' rel_union_all(rel_a, rel_b) -rel_union_all2 <- function(df_a, df_b, con) { - rethrow_rapi_rel_union_all2(df_a, df_b, con@conn_ref) +reldf_union_all <- function(df_a, df_b, con) { + rethrow_rapi_reldf_union_all(df_a, df_b, con@conn_ref) } #' Lazily compute a distinct result on a DuckDB relation object @@ -418,8 +423,8 @@ rel_distinct <- function(rel) { #' con <- DBI::dbConnect(duckdb()) #' rel <- rel_from_df(con, mtcars) #' rel2 <- rel_distinct(rel) -rel_distinct2 <- function(df, con) { - rethrow_rapi_rel_distinct2(df, con@conn_ref) +reldf_distinct <- function(df, con) { + rethrow_rapi_reldf_distinct(df, con@conn_ref) } #' SET INTERSECT on two DuckDB relation objects @@ -444,8 +449,8 @@ rel_set_intersect <- function(rel_a, rel_b) { #' rel_a <- rel_from_df(con, mtcars) #' rel_b <- rel_from_df(con, mtcars) #' rel_set_intersect_all(rel_a, rel_b) -rel_set_intersect2 <- function(df_a, df_b, con) { - rethrow_rapi_rel_set_intersect2(df_a, df_b, con@conn_ref) +reldf_set_intersect <- function(df_a, df_b, con) { + rethrow_rapi_reldf_set_intersect(df_a, df_b, con@conn_ref) } #' SET DIFF on two DuckDB relation objects @@ -470,8 +475,8 @@ rel_set_diff <- function(rel_a, rel_b) { #' rel_a <- rel_from_df(con, mtcars) #' rel_b <- rel_from_df(con, mtcars) #' rel_set_diff(rel_a, rel_b) -rel_set_diff2 <- function(df_a, df_b, con) { - rethrow_rapi_rel_set_diff2(df_a, df_b, con@conn_ref) +reldf_set_diff <- function(df_a, df_b, con) { + rethrow_rapi_reldf_set_diff(df_a, df_b, con@conn_ref) } #' SET SYMDIFF on two DuckDB relation objects @@ -496,8 +501,8 @@ rel_set_symdiff <- function(rel_a, rel_b) { #' rel_a <- rel_from_df(con, mtcars) #' rel_b <- rel_from_df(con, mtcars) #' rel_set_symdiff(rel_a, rel_b) -rel_set_symdiff2 <- function(df_a, df_b, con) { - rethrow_rapi_rel_set_symdiff2(df_a, df_b, con@conn_ref) +reldf_set_symdiff <- function(df_a, df_b, con) { + rethrow_rapi_reldf_set_symdiff(df_a, df_b, con@conn_ref) } #' Run a SQL query on a DuckDB relation object @@ -522,7 +527,7 @@ rel_sql <- function(rel, sql) { #' rel_explain(rel) rel_explain <- function(rel) { # Legacy - cat(rethrow_rapi_rel_explain(rel, "EXPLAIN_STANDARD", "DEFAULT")[[2]][[1]]) + cat(rethrow_rapi_reldf_explain(rel, "EXPLAIN_STANDARD", "DEFAULT")[[]][[1]]) invisible(NULL) } @@ -533,9 +538,9 @@ rel_explain <- function(rel) { #' con <- DBI::dbConnect(duckdb()) #' rel <- rel_from_df(con, mtcars) #' rel_explain(rel) -rel_explain2 <- function(df, con) { +reldf_explain <- function(df, con) { # Legacy - cat(rethrow_rapi_rel_explain2(df, con@conn_ref, "EXPLAIN_STANDARD", "DEFAULT")[[2]][[1]]) + cat(rethrow_rapi_reldf_explain(df, con@conn_ref, "EXPLAIN_STANDARD", "DEFAULT")[[2]][[1]]) invisible(NULL) } @@ -586,8 +591,8 @@ rel_alias <- function(rel) { #' con <- DBI::dbConnect(duckdb()) #' rel <- rel_from_df(con, mtcars) #' rel_alias(rel) -rel_alias2 <- function(df, con) { - rethrow_rapi_rel_alias2(df, con@conn_ref) +reldf_alias <- function(df, con) { + rethrow_rapi_reldf_alias(df, con@conn_ref) } #' Set the internal alias for a DuckDB relation object @@ -610,8 +615,8 @@ rel_set_alias <- function(rel, alias) { #' con <- DBI::dbConnect(duckdb()) #' rel <- rel_from_df(con, mtcars) #' rel_set_alias(rel, "my_new_alias") -rel_set_alias2 <- function(df, con, alias) { - rethrow_rapi_rel_set_alias2(df, con@conn_ref, alias) +reldf_set_alias <- function(df, con, alias) { + rethrow_rapi_reldf_set_alias(df, con@conn_ref, alias) } #' Transforms a relation object to a lazy data frame using altrep @@ -688,8 +693,8 @@ rel_from_sql <- function(con, sql) { #' con <- DBI::dbConnect(duckdb()) #' DBI::dbWriteTable(con, "mtcars", mtcars) #' rel <- rel_from_sql(con, "SELECT * FROM mtcars") -rel_from_sql2 <- function(con, sql) { - rethrow_rapi_rel_from_sql2(con@conn_ref, sql) +reldf_from_sql <- function(con, sql) { + rethrow_rapi_reldf_from_sql(con@conn_ref, sql) } #' Create a duckdb table relation from a table name @@ -712,8 +717,8 @@ rel_from_table <- function(con, table_name, schema_name = "MAIN") { #' con <- DBI::dbConnect(duckdb()) #' DBI::dbWriteTable(con, "mtcars", mtcars) #' rel <- rel_from_table(con, "mtcars") -rel_from_table2 <- function(con, table_name, schema_name = "MAIN") { - rethrow_rapi_rel_from_table2(con@conn_ref, schema_name, table_name) +reldf_from_table <- function(con, table_name, schema_name = "MAIN") { + rethrow_rapi_reldf_from_table(con@conn_ref, schema_name, table_name) } #' Convert a duckdb relation from a table-producing function @@ -738,48 +743,48 @@ rel_from_table_function <- function(con, function_name, positional_parameters = #' @examples #' con <- DBI::dbConnect(duckdb()) #' rel <- rel_from_table_function(con, 'generate_series', list(10L)) -rel_from_table_function2 <- function(con, function_name, positional_parameters = list(), named_parameters = list()) { - rethrow_rapi_rel_from_table_function2(con@conn_ref, function_name, positional_parameters, named_parameters) +reldf_from_table_function <- function(con, function_name, positional_parameters = list(), named_parameters = list()) { + rethrow_rapi_reldf_from_table_function(con@conn_ref, function_name, positional_parameters, named_parameters) } rel_to_parquet <- function(rel, file_name, options = list()) { rethrow_rapi_rel_to_parquet(rel, file_name, options) } -rel_to_parquet2 <- function(df, con, file_name, options = list()) { - rethrow_rapi_rel_to_parquet2(df, con@conn_ref, file_name, options) +reldf_to_parquet <- function(df, con, file_name, options = list()) { + rethrow_rapi_reldf_to_parquet(df, con@conn_ref, file_name, options) } rel_to_csv <- function(rel, file_name, options = list()) { rethrow_rapi_rel_to_csv(rel, file_name, options) } -rel_to_csv2 <- function(df, con, file_name, options = list()) { - rethrow_rapi_rel_to_csv2(df, con@conn_ref, file_name, options) +reldf_to_csv <- function(df, con, file_name, options = list()) { + rethrow_rapi_reldf_to_csv(df, con@conn_ref, file_name, options) } rel_to_table <- function(rel, schema_name, table_name, temporary) { rethrow_rapi_rel_to_table(rel, schema_name, table_name, temporary) } -rel_to_table2 <- function(df, con, schema_name, table_name, temporary) { - rethrow_rapi_rel_to_table2(df, con@conn_ref, schema_name, table_name, temporary) +reldf_to_table <- function(df, con, schema_name, table_name, temporary) { + rethrow_rapi_reldf_to_table(df, con@conn_ref, schema_name, table_name, temporary) } rel_insert <- function(rel, schema_name, table_name) { rethrow_rapi_rel_insert(rel, schema_name, table_name) } -rel_insert2 <- function(df, con, schema_name, table_name) { - rethrow_rapi_rel_insert2(df, con@conn_ref, schema_name, table_name) +reldf_insert <- function(df, con, schema_name, table_name) { + rethrow_rapi_reldf_insert(df, con@conn_ref, schema_name, table_name) } rel_names <- function(rel) { rethrow_rapi_rel_names(rel) } -rel_names2 <- function(df, con) { - rethrow_rapi_rel_names2(df, con@conn_ref) +reldf_names <- function(df, con) { + rethrow_rapi_reldf_names(df, con@conn_ref) } load_rfuns <- function() { diff --git a/R/rethrow-gen.R b/R/rethrow-gen.R index 4ebf5b1e5..b080b15ec 100644 --- a/R/rethrow-gen.R +++ b/R/rethrow-gen.R @@ -423,198 +423,198 @@ rethrow_rapi_rel_insert <- function(rel, schema_name, table_name, call = parent. ) } -rethrow_rapi_rel_names2 <- function(df, con, call = parent.frame(2)) { +rethrow_rapi_reldf_names <- function(df, con, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_names2(df, con), + rapi_reldf_names(df, con), error = function(e) { rethrow_error_from_rapi(e, call) } ) } -rethrow_rapi_rel_alias2 <- function(df, con, call = parent.frame(2)) { +rethrow_rapi_reldf_alias <- function(df, con, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_alias2(df, con), + rapi_reldf_alias(df, con), error = function(e) { rethrow_error_from_rapi(e, call) } ) } -rethrow_rapi_rel_set_alias2 <- function(df, con, alias, call = parent.frame(2)) { +rethrow_rapi_reldf_set_alias <- function(df, con, alias, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_set_alias2(df, con, alias), + rapi_reldf_set_alias(df, con, alias), error = function(e) { rethrow_error_from_rapi(e, call) } ) } -rethrow_rapi_rel_filter2 <- function(df, con, exprs, call = parent.frame(2)) { +rethrow_rapi_reldf_filter <- function(df, con, exprs, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_filter2(df, con, exprs), + rapi_reldf_filter(df, con, exprs), error = function(e) { rethrow_error_from_rapi(e, call) } ) } -rethrow_rapi_rel_project2 <- function(df, con, exprs, call = parent.frame(2)) { +rethrow_rapi_reldf_project <- function(df, con, exprs, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_project2(df, con, exprs), + rapi_reldf_project(df, con, exprs), error = function(e) { rethrow_error_from_rapi(e, call) } ) } -rethrow_rapi_rel_aggregate2 <- function(df, con, groups, aggregates, call = parent.frame(2)) { +rethrow_rapi_reldf_aggregate <- function(df, con, groups, aggregates, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_aggregate2(df, con, groups, aggregates), + rapi_reldf_aggregate(df, con, groups, aggregates), error = function(e) { rethrow_error_from_rapi(e, call) } ) } -rethrow_rapi_rel_order2 <- function(df, con, orders, ascending, call = parent.frame(2)) { +rethrow_rapi_reldf_order <- function(df, con, orders, ascending, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_order2(df, con, orders, ascending), + rapi_reldf_order(df, con, orders, ascending), error = function(e) { rethrow_error_from_rapi(e, call) } ) } -rethrow_rapi_rel_join2 <- function(left, right, con, conds, join, join_ref_type, call = parent.frame(2)) { +rethrow_rapi_reldf_join <- function(left, right, con, conds, join, join_ref_type, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_join2(left, right, con, conds, join, join_ref_type), + rapi_reldf_join(left, right, con, conds, join, join_ref_type), error = function(e) { rethrow_error_from_rapi(e, call) } ) } -rethrow_rapi_rel_union_all2 <- function(left, right, con, call = parent.frame(2)) { +rethrow_rapi_reldf_union_all <- function(left, right, con, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_union_all2(left, right, con), + rapi_reldf_union_all(left, right, con), error = function(e) { rethrow_error_from_rapi(e, call) } ) } -rethrow_rapi_rel_limit2 <- function(df, con, n, call = parent.frame(2)) { +rethrow_rapi_reldf_limit <- function(df, con, n, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_limit2(df, con, n), + rapi_reldf_limit(df, con, n), error = function(e) { rethrow_error_from_rapi(e, call) } ) } -rethrow_rapi_rel_distinct2 <- function(df, con, call = parent.frame(2)) { +rethrow_rapi_reldf_distinct <- function(df, con, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_distinct2(df, con), + rapi_reldf_distinct(df, con), error = function(e) { rethrow_error_from_rapi(e, call) } ) } -rethrow_rapi_rel_set_intersect2 <- function(left, right, con, call = parent.frame(2)) { +rethrow_rapi_reldf_set_intersect <- function(left, right, con, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_set_intersect2(left, right, con), + rapi_reldf_set_intersect(left, right, con), error = function(e) { rethrow_error_from_rapi(e, call) } ) } -rethrow_rapi_rel_set_diff2 <- function(left, right, con, call = parent.frame(2)) { +rethrow_rapi_reldf_set_diff <- function(left, right, con, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_set_diff2(left, right, con), + rapi_reldf_set_diff(left, right, con), error = function(e) { rethrow_error_from_rapi(e, call) } ) } -rethrow_rapi_rel_set_symdiff2 <- function(left, right, con, call = parent.frame(2)) { +rethrow_rapi_reldf_set_symdiff <- function(left, right, con, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_set_symdiff2(left, right, con), + rapi_reldf_set_symdiff(left, right, con), error = function(e) { rethrow_error_from_rapi(e, call) } ) } -rethrow_rapi_rel_from_sql2 <- function(con, sql, call = parent.frame(2)) { +rethrow_rapi_reldf_from_sql <- function(con, sql, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_from_sql2(con, sql), + rapi_reldf_from_sql(con, sql), error = function(e) { rethrow_error_from_rapi(e, call) } ) } -rethrow_rapi_rel_from_table2 <- function(con, schema_name, table_name, call = parent.frame(2)) { +rethrow_rapi_reldf_from_table <- function(con, schema_name, table_name, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_from_table2(con, schema_name, table_name), + rapi_reldf_from_table(con, schema_name, table_name), error = function(e) { rethrow_error_from_rapi(e, call) } ) } -rethrow_rapi_rel_from_table_function2 <- function(con, function_name, positional_parameters_sexps, named_parameters_sexps, call = parent.frame(2)) { +rethrow_rapi_reldf_from_table_function <- function(con, function_name, positional_parameters_sexps, named_parameters_sexps, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_from_table_function2(con, function_name, positional_parameters_sexps, named_parameters_sexps), + rapi_reldf_from_table_function(con, function_name, positional_parameters_sexps, named_parameters_sexps), error = function(e) { rethrow_error_from_rapi(e, call) } ) } -rethrow_rapi_rel_explain2 <- function(df, con, type, format, call = parent.frame(2)) { +rethrow_rapi_reldf_explain <- function(df, con, type, format, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_explain2(df, con, type, format), + rapi_reldf_explain(df, con, type, format), error = function(e) { rethrow_error_from_rapi(e, call) } ) } -rethrow_rapi_rel_to_parquet2 <- function(df, con, file_name, options_sexps, call = parent.frame(2)) { +rethrow_rapi_reldf_to_parquet <- function(df, con, file_name, options_sexps, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_to_parquet2(df, con, file_name, options_sexps), + rapi_reldf_to_parquet(df, con, file_name, options_sexps), error = function(e) { rethrow_error_from_rapi(e, call) } ) } -rethrow_rapi_rel_to_csv2 <- function(df, con, file_name, options_sexps, call = parent.frame(2)) { +rethrow_rapi_reldf_to_csv <- function(df, con, file_name, options_sexps, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_to_csv2(df, con, file_name, options_sexps), + rapi_reldf_to_csv(df, con, file_name, options_sexps), error = function(e) { rethrow_error_from_rapi(e, call) } ) } -rethrow_rapi_rel_to_table2 <- function(df, con, schema_name, table_name, temporary, call = parent.frame(2)) { +rethrow_rapi_reldf_to_table <- function(df, con, schema_name, table_name, temporary, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_to_table2(df, con, schema_name, table_name, temporary), + rapi_reldf_to_table(df, con, schema_name, table_name, temporary), error = function(e) { rethrow_error_from_rapi(e, call) } ) } -rethrow_rapi_rel_insert2 <- function(df, con, schema_name, table_name, call = parent.frame(2)) { +rethrow_rapi_reldf_insert <- function(df, con, schema_name, table_name, call = parent.frame(2)) { rlang::try_fetch( - rapi_rel_insert2(df, con, schema_name, table_name), + rapi_reldf_insert(df, con, schema_name, table_name), error = function(e) { rethrow_error_from_rapi(e, call) } @@ -768,28 +768,28 @@ rethrow_restore <- function() { rethrow_rapi_rel_to_csv <<- rapi_rel_to_csv rethrow_rapi_rel_to_table <<- rapi_rel_to_table rethrow_rapi_rel_insert <<- rapi_rel_insert - rethrow_rapi_rel_names2 <<- rapi_rel_names2 - rethrow_rapi_rel_alias2 <<- rapi_rel_alias2 - rethrow_rapi_rel_set_alias2 <<- rapi_rel_set_alias2 - rethrow_rapi_rel_filter2 <<- rapi_rel_filter2 - rethrow_rapi_rel_project2 <<- rapi_rel_project2 - rethrow_rapi_rel_aggregate2 <<- rapi_rel_aggregate2 - rethrow_rapi_rel_order2 <<- rapi_rel_order2 - rethrow_rapi_rel_join2 <<- rapi_rel_join2 - rethrow_rapi_rel_union_all2 <<- rapi_rel_union_all2 - rethrow_rapi_rel_limit2 <<- rapi_rel_limit2 - rethrow_rapi_rel_distinct2 <<- rapi_rel_distinct2 - rethrow_rapi_rel_set_intersect2 <<- rapi_rel_set_intersect2 - rethrow_rapi_rel_set_diff2 <<- rapi_rel_set_diff2 - rethrow_rapi_rel_set_symdiff2 <<- rapi_rel_set_symdiff2 - rethrow_rapi_rel_from_sql2 <<- rapi_rel_from_sql2 - rethrow_rapi_rel_from_table2 <<- rapi_rel_from_table2 - rethrow_rapi_rel_from_table_function2 <<- rapi_rel_from_table_function2 - rethrow_rapi_rel_explain2 <<- rapi_rel_explain2 - rethrow_rapi_rel_to_parquet2 <<- rapi_rel_to_parquet2 - rethrow_rapi_rel_to_csv2 <<- rapi_rel_to_csv2 - rethrow_rapi_rel_to_table2 <<- rapi_rel_to_table2 - rethrow_rapi_rel_insert2 <<- rapi_rel_insert2 + rethrow_rapi_reldf_names <<- rapi_reldf_names + rethrow_rapi_reldf_alias <<- rapi_reldf_alias + rethrow_rapi_reldf_set_alias <<- rapi_reldf_set_alias + rethrow_rapi_reldf_filter <<- rapi_reldf_filter + rethrow_rapi_reldf_project <<- rapi_reldf_project + rethrow_rapi_reldf_aggregate <<- rapi_reldf_aggregate + rethrow_rapi_reldf_order <<- rapi_reldf_order + rethrow_rapi_reldf_join <<- rapi_reldf_join + rethrow_rapi_reldf_union_all <<- rapi_reldf_union_all + rethrow_rapi_reldf_limit <<- rapi_reldf_limit + rethrow_rapi_reldf_distinct <<- rapi_reldf_distinct + rethrow_rapi_reldf_set_intersect <<- rapi_reldf_set_intersect + rethrow_rapi_reldf_set_diff <<- rapi_reldf_set_diff + rethrow_rapi_reldf_set_symdiff <<- rapi_reldf_set_symdiff + rethrow_rapi_reldf_from_sql <<- rapi_reldf_from_sql + rethrow_rapi_reldf_from_table <<- rapi_reldf_from_table + rethrow_rapi_reldf_from_table_function <<- rapi_reldf_from_table_function + rethrow_rapi_reldf_explain <<- rapi_reldf_explain + rethrow_rapi_reldf_to_parquet <<- rapi_reldf_to_parquet + rethrow_rapi_reldf_to_csv <<- rapi_reldf_to_csv + rethrow_rapi_reldf_to_table <<- rapi_reldf_to_table + rethrow_rapi_reldf_insert <<- rapi_reldf_insert rethrow_rapi_rel_to_altrep <<- rapi_rel_to_altrep rethrow_rapi_rel_from_altrep_df <<- rapi_rel_from_altrep_df rethrow_rapi_release <<- rapi_release diff --git a/src/cpp11.cpp b/src/cpp11.cpp index 0a3854290..98a2f9209 100644 --- a/src/cpp11.cpp +++ b/src/cpp11.cpp @@ -347,160 +347,160 @@ extern "C" SEXP _duckdb_rapi_rel_insert(SEXP rel, SEXP schema_name, SEXP table_n END_CPP11 } // relational2.cpp -SEXP rapi_rel_names2(data_frame df, duckdb::conn_eptr_t con); -extern "C" SEXP _duckdb_rapi_rel_names2(SEXP df, SEXP con) { +SEXP rapi_reldf_names(data_frame df, duckdb::conn_eptr_t con); +extern "C" SEXP _duckdb_rapi_reldf_names(SEXP df, SEXP con) { BEGIN_CPP11 - return cpp11::as_sexp(rapi_rel_names2(cpp11::as_cpp>(df), cpp11::as_cpp>(con))); + return cpp11::as_sexp(rapi_reldf_names(cpp11::as_cpp>(df), cpp11::as_cpp>(con))); END_CPP11 } // relational2.cpp -std::string rapi_rel_alias2(data_frame df, duckdb::conn_eptr_t con); -extern "C" SEXP _duckdb_rapi_rel_alias2(SEXP df, SEXP con) { +std::string rapi_reldf_alias(data_frame df, duckdb::conn_eptr_t con); +extern "C" SEXP _duckdb_rapi_reldf_alias(SEXP df, SEXP con) { BEGIN_CPP11 - return cpp11::as_sexp(rapi_rel_alias2(cpp11::as_cpp>(df), cpp11::as_cpp>(con))); + return cpp11::as_sexp(rapi_reldf_alias(cpp11::as_cpp>(df), cpp11::as_cpp>(con))); END_CPP11 } // relational2.cpp -SEXP rapi_rel_set_alias2(data_frame df, duckdb::conn_eptr_t con, std::string alias); -extern "C" SEXP _duckdb_rapi_rel_set_alias2(SEXP df, SEXP con, SEXP alias) { +SEXP rapi_reldf_set_alias(data_frame df, duckdb::conn_eptr_t con, std::string alias); +extern "C" SEXP _duckdb_rapi_reldf_set_alias(SEXP df, SEXP con, SEXP alias) { BEGIN_CPP11 - return cpp11::as_sexp(rapi_rel_set_alias2(cpp11::as_cpp>(df), cpp11::as_cpp>(con), cpp11::as_cpp>(alias))); + return cpp11::as_sexp(rapi_reldf_set_alias(cpp11::as_cpp>(df), cpp11::as_cpp>(con), cpp11::as_cpp>(alias))); END_CPP11 } // relational2.cpp -SEXP rapi_rel_filter2(data_frame df, duckdb::conn_eptr_t con, list exprs); -extern "C" SEXP _duckdb_rapi_rel_filter2(SEXP df, SEXP con, SEXP exprs) { +SEXP rapi_reldf_filter(data_frame df, duckdb::conn_eptr_t con, list exprs); +extern "C" SEXP _duckdb_rapi_reldf_filter(SEXP df, SEXP con, SEXP exprs) { BEGIN_CPP11 - return cpp11::as_sexp(rapi_rel_filter2(cpp11::as_cpp>(df), cpp11::as_cpp>(con), cpp11::as_cpp>(exprs))); + return cpp11::as_sexp(rapi_reldf_filter(cpp11::as_cpp>(df), cpp11::as_cpp>(con), cpp11::as_cpp>(exprs))); END_CPP11 } // relational2.cpp -SEXP rapi_rel_project2(data_frame df, duckdb::conn_eptr_t con, list exprs); -extern "C" SEXP _duckdb_rapi_rel_project2(SEXP df, SEXP con, SEXP exprs) { +SEXP rapi_reldf_project(data_frame df, duckdb::conn_eptr_t con, list exprs); +extern "C" SEXP _duckdb_rapi_reldf_project(SEXP df, SEXP con, SEXP exprs) { BEGIN_CPP11 - return cpp11::as_sexp(rapi_rel_project2(cpp11::as_cpp>(df), cpp11::as_cpp>(con), cpp11::as_cpp>(exprs))); + return cpp11::as_sexp(rapi_reldf_project(cpp11::as_cpp>(df), cpp11::as_cpp>(con), cpp11::as_cpp>(exprs))); END_CPP11 } // relational2.cpp -SEXP rapi_rel_aggregate2(data_frame df, duckdb::conn_eptr_t con, list groups, list aggregates); -extern "C" SEXP _duckdb_rapi_rel_aggregate2(SEXP df, SEXP con, SEXP groups, SEXP aggregates) { +SEXP rapi_reldf_aggregate(data_frame df, duckdb::conn_eptr_t con, list groups, list aggregates); +extern "C" SEXP _duckdb_rapi_reldf_aggregate(SEXP df, SEXP con, SEXP groups, SEXP aggregates) { BEGIN_CPP11 - return cpp11::as_sexp(rapi_rel_aggregate2(cpp11::as_cpp>(df), cpp11::as_cpp>(con), cpp11::as_cpp>(groups), cpp11::as_cpp>(aggregates))); + return cpp11::as_sexp(rapi_reldf_aggregate(cpp11::as_cpp>(df), cpp11::as_cpp>(con), cpp11::as_cpp>(groups), cpp11::as_cpp>(aggregates))); END_CPP11 } // relational2.cpp -SEXP rapi_rel_order2(data_frame df, duckdb::conn_eptr_t con, list orders, r_vector ascending); -extern "C" SEXP _duckdb_rapi_rel_order2(SEXP df, SEXP con, SEXP orders, SEXP ascending) { +SEXP rapi_reldf_order(data_frame df, duckdb::conn_eptr_t con, list orders, r_vector ascending); +extern "C" SEXP _duckdb_rapi_reldf_order(SEXP df, SEXP con, SEXP orders, SEXP ascending) { BEGIN_CPP11 - return cpp11::as_sexp(rapi_rel_order2(cpp11::as_cpp>(df), cpp11::as_cpp>(con), cpp11::as_cpp>(orders), cpp11::as_cpp>>(ascending))); + return cpp11::as_sexp(rapi_reldf_order(cpp11::as_cpp>(df), cpp11::as_cpp>(con), cpp11::as_cpp>(orders), cpp11::as_cpp>>(ascending))); END_CPP11 } // relational2.cpp -SEXP rapi_rel_join2(data_frame left, data_frame right, duckdb::conn_eptr_t con, list conds, std::string join, std::string join_ref_type); -extern "C" SEXP _duckdb_rapi_rel_join2(SEXP left, SEXP right, SEXP con, SEXP conds, SEXP join, SEXP join_ref_type) { +SEXP rapi_reldf_join(data_frame left, data_frame right, duckdb::conn_eptr_t con, list conds, std::string join, std::string join_ref_type); +extern "C" SEXP _duckdb_rapi_reldf_join(SEXP left, SEXP right, SEXP con, SEXP conds, SEXP join, SEXP join_ref_type) { BEGIN_CPP11 - return cpp11::as_sexp(rapi_rel_join2(cpp11::as_cpp>(left), cpp11::as_cpp>(right), cpp11::as_cpp>(con), cpp11::as_cpp>(conds), cpp11::as_cpp>(join), cpp11::as_cpp>(join_ref_type))); + return cpp11::as_sexp(rapi_reldf_join(cpp11::as_cpp>(left), cpp11::as_cpp>(right), cpp11::as_cpp>(con), cpp11::as_cpp>(conds), cpp11::as_cpp>(join), cpp11::as_cpp>(join_ref_type))); END_CPP11 } // relational2.cpp -SEXP rapi_rel_union_all2(data_frame left, data_frame right, duckdb::conn_eptr_t con); -extern "C" SEXP _duckdb_rapi_rel_union_all2(SEXP left, SEXP right, SEXP con) { +SEXP rapi_reldf_union_all(data_frame left, data_frame right, duckdb::conn_eptr_t con); +extern "C" SEXP _duckdb_rapi_reldf_union_all(SEXP left, SEXP right, SEXP con) { BEGIN_CPP11 - return cpp11::as_sexp(rapi_rel_union_all2(cpp11::as_cpp>(left), cpp11::as_cpp>(right), cpp11::as_cpp>(con))); + return cpp11::as_sexp(rapi_reldf_union_all(cpp11::as_cpp>(left), cpp11::as_cpp>(right), cpp11::as_cpp>(con))); END_CPP11 } // relational2.cpp -SEXP rapi_rel_limit2(data_frame df, duckdb::conn_eptr_t con, int64_t n); -extern "C" SEXP _duckdb_rapi_rel_limit2(SEXP df, SEXP con, SEXP n) { +SEXP rapi_reldf_limit(data_frame df, duckdb::conn_eptr_t con, int64_t n); +extern "C" SEXP _duckdb_rapi_reldf_limit(SEXP df, SEXP con, SEXP n) { BEGIN_CPP11 - return cpp11::as_sexp(rapi_rel_limit2(cpp11::as_cpp>(df), cpp11::as_cpp>(con), cpp11::as_cpp>(n))); + return cpp11::as_sexp(rapi_reldf_limit(cpp11::as_cpp>(df), cpp11::as_cpp>(con), cpp11::as_cpp>(n))); END_CPP11 } // relational2.cpp -SEXP rapi_rel_distinct2(data_frame df, duckdb::conn_eptr_t con); -extern "C" SEXP _duckdb_rapi_rel_distinct2(SEXP df, SEXP con) { +SEXP rapi_reldf_distinct(data_frame df, duckdb::conn_eptr_t con); +extern "C" SEXP _duckdb_rapi_reldf_distinct(SEXP df, SEXP con) { BEGIN_CPP11 - return cpp11::as_sexp(rapi_rel_distinct2(cpp11::as_cpp>(df), cpp11::as_cpp>(con))); + return cpp11::as_sexp(rapi_reldf_distinct(cpp11::as_cpp>(df), cpp11::as_cpp>(con))); END_CPP11 } // relational2.cpp -SEXP rapi_rel_set_intersect2(data_frame left, data_frame right, duckdb::conn_eptr_t con); -extern "C" SEXP _duckdb_rapi_rel_set_intersect2(SEXP left, SEXP right, SEXP con) { +SEXP rapi_reldf_set_intersect(data_frame left, data_frame right, duckdb::conn_eptr_t con); +extern "C" SEXP _duckdb_rapi_reldf_set_intersect(SEXP left, SEXP right, SEXP con) { BEGIN_CPP11 - return cpp11::as_sexp(rapi_rel_set_intersect2(cpp11::as_cpp>(left), cpp11::as_cpp>(right), cpp11::as_cpp>(con))); + return cpp11::as_sexp(rapi_reldf_set_intersect(cpp11::as_cpp>(left), cpp11::as_cpp>(right), cpp11::as_cpp>(con))); END_CPP11 } // relational2.cpp -SEXP rapi_rel_set_diff2(data_frame left, data_frame right, duckdb::conn_eptr_t con); -extern "C" SEXP _duckdb_rapi_rel_set_diff2(SEXP left, SEXP right, SEXP con) { +SEXP rapi_reldf_set_diff(data_frame left, data_frame right, duckdb::conn_eptr_t con); +extern "C" SEXP _duckdb_rapi_reldf_set_diff(SEXP left, SEXP right, SEXP con) { BEGIN_CPP11 - return cpp11::as_sexp(rapi_rel_set_diff2(cpp11::as_cpp>(left), cpp11::as_cpp>(right), cpp11::as_cpp>(con))); + return cpp11::as_sexp(rapi_reldf_set_diff(cpp11::as_cpp>(left), cpp11::as_cpp>(right), cpp11::as_cpp>(con))); END_CPP11 } // relational2.cpp -SEXP rapi_rel_set_symdiff2(data_frame left, data_frame right, duckdb::conn_eptr_t con); -extern "C" SEXP _duckdb_rapi_rel_set_symdiff2(SEXP left, SEXP right, SEXP con) { +SEXP rapi_reldf_set_symdiff(data_frame left, data_frame right, duckdb::conn_eptr_t con); +extern "C" SEXP _duckdb_rapi_reldf_set_symdiff(SEXP left, SEXP right, SEXP con) { BEGIN_CPP11 - return cpp11::as_sexp(rapi_rel_set_symdiff2(cpp11::as_cpp>(left), cpp11::as_cpp>(right), cpp11::as_cpp>(con))); + return cpp11::as_sexp(rapi_reldf_set_symdiff(cpp11::as_cpp>(left), cpp11::as_cpp>(right), cpp11::as_cpp>(con))); END_CPP11 } // relational2.cpp -SEXP rapi_rel_from_sql2(duckdb::conn_eptr_t con, const std::string sql); -extern "C" SEXP _duckdb_rapi_rel_from_sql2(SEXP con, SEXP sql) { +SEXP rapi_reldf_from_sql(duckdb::conn_eptr_t con, const std::string sql); +extern "C" SEXP _duckdb_rapi_reldf_from_sql(SEXP con, SEXP sql) { BEGIN_CPP11 - return cpp11::as_sexp(rapi_rel_from_sql2(cpp11::as_cpp>(con), cpp11::as_cpp>(sql))); + return cpp11::as_sexp(rapi_reldf_from_sql(cpp11::as_cpp>(con), cpp11::as_cpp>(sql))); END_CPP11 } // relational2.cpp -SEXP rapi_rel_from_table2(duckdb::conn_eptr_t con, const std::string schema_name, const std::string table_name); -extern "C" SEXP _duckdb_rapi_rel_from_table2(SEXP con, SEXP schema_name, SEXP table_name) { +SEXP rapi_reldf_from_table(duckdb::conn_eptr_t con, const std::string schema_name, const std::string table_name); +extern "C" SEXP _duckdb_rapi_reldf_from_table(SEXP con, SEXP schema_name, SEXP table_name) { BEGIN_CPP11 - return cpp11::as_sexp(rapi_rel_from_table2(cpp11::as_cpp>(con), cpp11::as_cpp>(schema_name), cpp11::as_cpp>(table_name))); + return cpp11::as_sexp(rapi_reldf_from_table(cpp11::as_cpp>(con), cpp11::as_cpp>(schema_name), cpp11::as_cpp>(table_name))); END_CPP11 } // relational2.cpp -SEXP rapi_rel_from_table_function2(duckdb::conn_eptr_t con, const std::string function_name, list positional_parameters_sexps, list named_parameters_sexps); -extern "C" SEXP _duckdb_rapi_rel_from_table_function2(SEXP con, SEXP function_name, SEXP positional_parameters_sexps, SEXP named_parameters_sexps) { +SEXP rapi_reldf_from_table_function(duckdb::conn_eptr_t con, const std::string function_name, list positional_parameters_sexps, list named_parameters_sexps); +extern "C" SEXP _duckdb_rapi_reldf_from_table_function(SEXP con, SEXP function_name, SEXP positional_parameters_sexps, SEXP named_parameters_sexps) { BEGIN_CPP11 - return cpp11::as_sexp(rapi_rel_from_table_function2(cpp11::as_cpp>(con), cpp11::as_cpp>(function_name), cpp11::as_cpp>(positional_parameters_sexps), cpp11::as_cpp>(named_parameters_sexps))); + return cpp11::as_sexp(rapi_reldf_from_table_function(cpp11::as_cpp>(con), cpp11::as_cpp>(function_name), cpp11::as_cpp>(positional_parameters_sexps), cpp11::as_cpp>(named_parameters_sexps))); END_CPP11 } // relational2.cpp -SEXP rapi_rel_explain2(data_frame df, duckdb::conn_eptr_t con, std::string type, std::string format); -extern "C" SEXP _duckdb_rapi_rel_explain2(SEXP df, SEXP con, SEXP type, SEXP format) { +SEXP rapi_reldf_explain(data_frame df, duckdb::conn_eptr_t con, std::string type, std::string format); +extern "C" SEXP _duckdb_rapi_reldf_explain(SEXP df, SEXP con, SEXP type, SEXP format) { BEGIN_CPP11 - return cpp11::as_sexp(rapi_rel_explain2(cpp11::as_cpp>(df), cpp11::as_cpp>(con), cpp11::as_cpp>(type), cpp11::as_cpp>(format))); + return cpp11::as_sexp(rapi_reldf_explain(cpp11::as_cpp>(df), cpp11::as_cpp>(con), cpp11::as_cpp>(type), cpp11::as_cpp>(format))); END_CPP11 } // relational2.cpp -void rapi_rel_to_parquet2(data_frame df, duckdb::conn_eptr_t con, std::string file_name, list options_sexps); -extern "C" SEXP _duckdb_rapi_rel_to_parquet2(SEXP df, SEXP con, SEXP file_name, SEXP options_sexps) { +void rapi_reldf_to_parquet(data_frame df, duckdb::conn_eptr_t con, std::string file_name, list options_sexps); +extern "C" SEXP _duckdb_rapi_reldf_to_parquet(SEXP df, SEXP con, SEXP file_name, SEXP options_sexps) { BEGIN_CPP11 - rapi_rel_to_parquet2(cpp11::as_cpp>(df), cpp11::as_cpp>(con), cpp11::as_cpp>(file_name), cpp11::as_cpp>(options_sexps)); + rapi_reldf_to_parquet(cpp11::as_cpp>(df), cpp11::as_cpp>(con), cpp11::as_cpp>(file_name), cpp11::as_cpp>(options_sexps)); return R_NilValue; END_CPP11 } // relational2.cpp -void rapi_rel_to_csv2(data_frame df, duckdb::conn_eptr_t con, std::string file_name, list options_sexps); -extern "C" SEXP _duckdb_rapi_rel_to_csv2(SEXP df, SEXP con, SEXP file_name, SEXP options_sexps) { +void rapi_reldf_to_csv(data_frame df, duckdb::conn_eptr_t con, std::string file_name, list options_sexps); +extern "C" SEXP _duckdb_rapi_reldf_to_csv(SEXP df, SEXP con, SEXP file_name, SEXP options_sexps) { BEGIN_CPP11 - rapi_rel_to_csv2(cpp11::as_cpp>(df), cpp11::as_cpp>(con), cpp11::as_cpp>(file_name), cpp11::as_cpp>(options_sexps)); + rapi_reldf_to_csv(cpp11::as_cpp>(df), cpp11::as_cpp>(con), cpp11::as_cpp>(file_name), cpp11::as_cpp>(options_sexps)); return R_NilValue; END_CPP11 } // relational2.cpp -void rapi_rel_to_table2(data_frame df, duckdb::conn_eptr_t con, std::string schema_name, std::string table_name, bool temporary); -extern "C" SEXP _duckdb_rapi_rel_to_table2(SEXP df, SEXP con, SEXP schema_name, SEXP table_name, SEXP temporary) { +void rapi_reldf_to_table(data_frame df, duckdb::conn_eptr_t con, std::string schema_name, std::string table_name, bool temporary); +extern "C" SEXP _duckdb_rapi_reldf_to_table(SEXP df, SEXP con, SEXP schema_name, SEXP table_name, SEXP temporary) { BEGIN_CPP11 - rapi_rel_to_table2(cpp11::as_cpp>(df), cpp11::as_cpp>(con), cpp11::as_cpp>(schema_name), cpp11::as_cpp>(table_name), cpp11::as_cpp>(temporary)); + rapi_reldf_to_table(cpp11::as_cpp>(df), cpp11::as_cpp>(con), cpp11::as_cpp>(schema_name), cpp11::as_cpp>(table_name), cpp11::as_cpp>(temporary)); return R_NilValue; END_CPP11 } // relational2.cpp -void rapi_rel_insert2(data_frame df, duckdb::conn_eptr_t con, std::string schema_name, std::string table_name); -extern "C" SEXP _duckdb_rapi_rel_insert2(SEXP df, SEXP con, SEXP schema_name, SEXP table_name) { +void rapi_reldf_insert(data_frame df, duckdb::conn_eptr_t con, std::string schema_name, std::string table_name); +extern "C" SEXP _duckdb_rapi_reldf_insert(SEXP df, SEXP con, SEXP schema_name, SEXP table_name) { BEGIN_CPP11 - rapi_rel_insert2(cpp11::as_cpp>(df), cpp11::as_cpp>(con), cpp11::as_cpp>(schema_name), cpp11::as_cpp>(table_name)); + rapi_reldf_insert(cpp11::as_cpp>(df), cpp11::as_cpp>(con), cpp11::as_cpp>(schema_name), cpp11::as_cpp>(table_name)); return R_NilValue; END_CPP11 } @@ -586,86 +586,86 @@ extern "C" SEXP _duckdb_rapi_load_rfuns(SEXP dual) { extern "C" { static const R_CallMethodDef CallEntries[] = { - {"_duckdb_rapi_adbc_init_func", (DL_FUNC) &_duckdb_rapi_adbc_init_func, 0}, - {"_duckdb_rapi_bind", (DL_FUNC) &_duckdb_rapi_bind, 4}, - {"_duckdb_rapi_connect", (DL_FUNC) &_duckdb_rapi_connect, 1}, - {"_duckdb_rapi_disconnect", (DL_FUNC) &_duckdb_rapi_disconnect, 1}, - {"_duckdb_rapi_execute", (DL_FUNC) &_duckdb_rapi_execute, 3}, - {"_duckdb_rapi_execute_arrow", (DL_FUNC) &_duckdb_rapi_execute_arrow, 2}, - {"_duckdb_rapi_expr_comparison", (DL_FUNC) &_duckdb_rapi_expr_comparison, 2}, - {"_duckdb_rapi_expr_constant", (DL_FUNC) &_duckdb_rapi_expr_constant, 1}, - {"_duckdb_rapi_expr_function", (DL_FUNC) &_duckdb_rapi_expr_function, 4}, - {"_duckdb_rapi_expr_reference", (DL_FUNC) &_duckdb_rapi_expr_reference, 1}, - {"_duckdb_rapi_expr_set_alias", (DL_FUNC) &_duckdb_rapi_expr_set_alias, 2}, - {"_duckdb_rapi_expr_tostring", (DL_FUNC) &_duckdb_rapi_expr_tostring, 1}, - {"_duckdb_rapi_expr_window", (DL_FUNC) &_duckdb_rapi_expr_window, 9}, - {"_duckdb_rapi_get_null_SEXP_ptr", (DL_FUNC) &_duckdb_rapi_get_null_SEXP_ptr, 0}, - {"_duckdb_rapi_is_locked", (DL_FUNC) &_duckdb_rapi_is_locked, 1}, - {"_duckdb_rapi_list_arrow", (DL_FUNC) &_duckdb_rapi_list_arrow, 1}, - {"_duckdb_rapi_load_rfuns", (DL_FUNC) &_duckdb_rapi_load_rfuns, 1}, - {"_duckdb_rapi_lock", (DL_FUNC) &_duckdb_rapi_lock, 1}, - {"_duckdb_rapi_prepare", (DL_FUNC) &_duckdb_rapi_prepare, 3}, - {"_duckdb_rapi_ptr_to_str", (DL_FUNC) &_duckdb_rapi_ptr_to_str, 1}, - {"_duckdb_rapi_record_batch", (DL_FUNC) &_duckdb_rapi_record_batch, 2}, - {"_duckdb_rapi_register_arrow", (DL_FUNC) &_duckdb_rapi_register_arrow, 4}, - {"_duckdb_rapi_register_df", (DL_FUNC) &_duckdb_rapi_register_df, 6}, - {"_duckdb_rapi_rel_aggregate", (DL_FUNC) &_duckdb_rapi_rel_aggregate, 3}, - {"_duckdb_rapi_rel_aggregate2", (DL_FUNC) &_duckdb_rapi_rel_aggregate2, 4}, - {"_duckdb_rapi_rel_alias", (DL_FUNC) &_duckdb_rapi_rel_alias, 1}, - {"_duckdb_rapi_rel_alias2", (DL_FUNC) &_duckdb_rapi_rel_alias2, 2}, - {"_duckdb_rapi_rel_distinct", (DL_FUNC) &_duckdb_rapi_rel_distinct, 1}, - {"_duckdb_rapi_rel_distinct2", (DL_FUNC) &_duckdb_rapi_rel_distinct2, 2}, - {"_duckdb_rapi_rel_explain", (DL_FUNC) &_duckdb_rapi_rel_explain, 3}, - {"_duckdb_rapi_rel_explain2", (DL_FUNC) &_duckdb_rapi_rel_explain2, 4}, - {"_duckdb_rapi_rel_filter", (DL_FUNC) &_duckdb_rapi_rel_filter, 2}, - {"_duckdb_rapi_rel_filter2", (DL_FUNC) &_duckdb_rapi_rel_filter2, 3}, - {"_duckdb_rapi_rel_from_altrep_df", (DL_FUNC) &_duckdb_rapi_rel_from_altrep_df, 3}, - {"_duckdb_rapi_rel_from_df", (DL_FUNC) &_duckdb_rapi_rel_from_df, 3}, - {"_duckdb_rapi_rel_from_sql", (DL_FUNC) &_duckdb_rapi_rel_from_sql, 2}, - {"_duckdb_rapi_rel_from_sql2", (DL_FUNC) &_duckdb_rapi_rel_from_sql2, 2}, - {"_duckdb_rapi_rel_from_table", (DL_FUNC) &_duckdb_rapi_rel_from_table, 3}, - {"_duckdb_rapi_rel_from_table2", (DL_FUNC) &_duckdb_rapi_rel_from_table2, 3}, - {"_duckdb_rapi_rel_from_table_function", (DL_FUNC) &_duckdb_rapi_rel_from_table_function, 4}, - {"_duckdb_rapi_rel_from_table_function2", (DL_FUNC) &_duckdb_rapi_rel_from_table_function2, 4}, - {"_duckdb_rapi_rel_insert", (DL_FUNC) &_duckdb_rapi_rel_insert, 3}, - {"_duckdb_rapi_rel_insert2", (DL_FUNC) &_duckdb_rapi_rel_insert2, 4}, - {"_duckdb_rapi_rel_join", (DL_FUNC) &_duckdb_rapi_rel_join, 5}, - {"_duckdb_rapi_rel_join2", (DL_FUNC) &_duckdb_rapi_rel_join2, 6}, - {"_duckdb_rapi_rel_limit", (DL_FUNC) &_duckdb_rapi_rel_limit, 2}, - {"_duckdb_rapi_rel_limit2", (DL_FUNC) &_duckdb_rapi_rel_limit2, 3}, - {"_duckdb_rapi_rel_names", (DL_FUNC) &_duckdb_rapi_rel_names, 1}, - {"_duckdb_rapi_rel_names2", (DL_FUNC) &_duckdb_rapi_rel_names2, 2}, - {"_duckdb_rapi_rel_order", (DL_FUNC) &_duckdb_rapi_rel_order, 3}, - {"_duckdb_rapi_rel_order2", (DL_FUNC) &_duckdb_rapi_rel_order2, 4}, - {"_duckdb_rapi_rel_project", (DL_FUNC) &_duckdb_rapi_rel_project, 2}, - {"_duckdb_rapi_rel_project2", (DL_FUNC) &_duckdb_rapi_rel_project2, 3}, - {"_duckdb_rapi_rel_set_alias", (DL_FUNC) &_duckdb_rapi_rel_set_alias, 2}, - {"_duckdb_rapi_rel_set_alias2", (DL_FUNC) &_duckdb_rapi_rel_set_alias2, 3}, - {"_duckdb_rapi_rel_set_diff", (DL_FUNC) &_duckdb_rapi_rel_set_diff, 2}, - {"_duckdb_rapi_rel_set_diff2", (DL_FUNC) &_duckdb_rapi_rel_set_diff2, 3}, - {"_duckdb_rapi_rel_set_intersect", (DL_FUNC) &_duckdb_rapi_rel_set_intersect, 2}, - {"_duckdb_rapi_rel_set_intersect2", (DL_FUNC) &_duckdb_rapi_rel_set_intersect2, 3}, - {"_duckdb_rapi_rel_set_symdiff", (DL_FUNC) &_duckdb_rapi_rel_set_symdiff, 2}, - {"_duckdb_rapi_rel_set_symdiff2", (DL_FUNC) &_duckdb_rapi_rel_set_symdiff2, 3}, - {"_duckdb_rapi_rel_sql", (DL_FUNC) &_duckdb_rapi_rel_sql, 2}, - {"_duckdb_rapi_rel_to_altrep", (DL_FUNC) &_duckdb_rapi_rel_to_altrep, 3}, - {"_duckdb_rapi_rel_to_csv", (DL_FUNC) &_duckdb_rapi_rel_to_csv, 3}, - {"_duckdb_rapi_rel_to_csv2", (DL_FUNC) &_duckdb_rapi_rel_to_csv2, 4}, - {"_duckdb_rapi_rel_to_df", (DL_FUNC) &_duckdb_rapi_rel_to_df, 1}, - {"_duckdb_rapi_rel_to_parquet", (DL_FUNC) &_duckdb_rapi_rel_to_parquet, 3}, - {"_duckdb_rapi_rel_to_parquet2", (DL_FUNC) &_duckdb_rapi_rel_to_parquet2, 4}, - {"_duckdb_rapi_rel_to_sql", (DL_FUNC) &_duckdb_rapi_rel_to_sql, 1}, - {"_duckdb_rapi_rel_to_table", (DL_FUNC) &_duckdb_rapi_rel_to_table, 4}, - {"_duckdb_rapi_rel_to_table2", (DL_FUNC) &_duckdb_rapi_rel_to_table2, 5}, - {"_duckdb_rapi_rel_tostring", (DL_FUNC) &_duckdb_rapi_rel_tostring, 2}, - {"_duckdb_rapi_rel_union_all", (DL_FUNC) &_duckdb_rapi_rel_union_all, 2}, - {"_duckdb_rapi_rel_union_all2", (DL_FUNC) &_duckdb_rapi_rel_union_all2, 3}, - {"_duckdb_rapi_release", (DL_FUNC) &_duckdb_rapi_release, 1}, - {"_duckdb_rapi_shutdown", (DL_FUNC) &_duckdb_rapi_shutdown, 1}, - {"_duckdb_rapi_startup", (DL_FUNC) &_duckdb_rapi_startup, 4}, - {"_duckdb_rapi_unlock", (DL_FUNC) &_duckdb_rapi_unlock, 1}, - {"_duckdb_rapi_unregister_arrow", (DL_FUNC) &_duckdb_rapi_unregister_arrow, 2}, - {"_duckdb_rapi_unregister_df", (DL_FUNC) &_duckdb_rapi_unregister_df, 2}, + {"_duckdb_rapi_adbc_init_func", (DL_FUNC) &_duckdb_rapi_adbc_init_func, 0}, + {"_duckdb_rapi_bind", (DL_FUNC) &_duckdb_rapi_bind, 4}, + {"_duckdb_rapi_connect", (DL_FUNC) &_duckdb_rapi_connect, 1}, + {"_duckdb_rapi_disconnect", (DL_FUNC) &_duckdb_rapi_disconnect, 1}, + {"_duckdb_rapi_execute", (DL_FUNC) &_duckdb_rapi_execute, 3}, + {"_duckdb_rapi_execute_arrow", (DL_FUNC) &_duckdb_rapi_execute_arrow, 2}, + {"_duckdb_rapi_expr_comparison", (DL_FUNC) &_duckdb_rapi_expr_comparison, 2}, + {"_duckdb_rapi_expr_constant", (DL_FUNC) &_duckdb_rapi_expr_constant, 1}, + {"_duckdb_rapi_expr_function", (DL_FUNC) &_duckdb_rapi_expr_function, 4}, + {"_duckdb_rapi_expr_reference", (DL_FUNC) &_duckdb_rapi_expr_reference, 1}, + {"_duckdb_rapi_expr_set_alias", (DL_FUNC) &_duckdb_rapi_expr_set_alias, 2}, + {"_duckdb_rapi_expr_tostring", (DL_FUNC) &_duckdb_rapi_expr_tostring, 1}, + {"_duckdb_rapi_expr_window", (DL_FUNC) &_duckdb_rapi_expr_window, 9}, + {"_duckdb_rapi_get_null_SEXP_ptr", (DL_FUNC) &_duckdb_rapi_get_null_SEXP_ptr, 0}, + {"_duckdb_rapi_is_locked", (DL_FUNC) &_duckdb_rapi_is_locked, 1}, + {"_duckdb_rapi_list_arrow", (DL_FUNC) &_duckdb_rapi_list_arrow, 1}, + {"_duckdb_rapi_load_rfuns", (DL_FUNC) &_duckdb_rapi_load_rfuns, 1}, + {"_duckdb_rapi_lock", (DL_FUNC) &_duckdb_rapi_lock, 1}, + {"_duckdb_rapi_prepare", (DL_FUNC) &_duckdb_rapi_prepare, 3}, + {"_duckdb_rapi_ptr_to_str", (DL_FUNC) &_duckdb_rapi_ptr_to_str, 1}, + {"_duckdb_rapi_record_batch", (DL_FUNC) &_duckdb_rapi_record_batch, 2}, + {"_duckdb_rapi_register_arrow", (DL_FUNC) &_duckdb_rapi_register_arrow, 4}, + {"_duckdb_rapi_register_df", (DL_FUNC) &_duckdb_rapi_register_df, 6}, + {"_duckdb_rapi_rel_aggregate", (DL_FUNC) &_duckdb_rapi_rel_aggregate, 3}, + {"_duckdb_rapi_rel_alias", (DL_FUNC) &_duckdb_rapi_rel_alias, 1}, + {"_duckdb_rapi_rel_distinct", (DL_FUNC) &_duckdb_rapi_rel_distinct, 1}, + {"_duckdb_rapi_rel_explain", (DL_FUNC) &_duckdb_rapi_rel_explain, 3}, + {"_duckdb_rapi_rel_filter", (DL_FUNC) &_duckdb_rapi_rel_filter, 2}, + {"_duckdb_rapi_rel_from_altrep_df", (DL_FUNC) &_duckdb_rapi_rel_from_altrep_df, 3}, + {"_duckdb_rapi_rel_from_df", (DL_FUNC) &_duckdb_rapi_rel_from_df, 3}, + {"_duckdb_rapi_rel_from_sql", (DL_FUNC) &_duckdb_rapi_rel_from_sql, 2}, + {"_duckdb_rapi_rel_from_table", (DL_FUNC) &_duckdb_rapi_rel_from_table, 3}, + {"_duckdb_rapi_rel_from_table_function", (DL_FUNC) &_duckdb_rapi_rel_from_table_function, 4}, + {"_duckdb_rapi_rel_insert", (DL_FUNC) &_duckdb_rapi_rel_insert, 3}, + {"_duckdb_rapi_rel_join", (DL_FUNC) &_duckdb_rapi_rel_join, 5}, + {"_duckdb_rapi_rel_limit", (DL_FUNC) &_duckdb_rapi_rel_limit, 2}, + {"_duckdb_rapi_rel_names", (DL_FUNC) &_duckdb_rapi_rel_names, 1}, + {"_duckdb_rapi_rel_order", (DL_FUNC) &_duckdb_rapi_rel_order, 3}, + {"_duckdb_rapi_rel_project", (DL_FUNC) &_duckdb_rapi_rel_project, 2}, + {"_duckdb_rapi_rel_set_alias", (DL_FUNC) &_duckdb_rapi_rel_set_alias, 2}, + {"_duckdb_rapi_rel_set_diff", (DL_FUNC) &_duckdb_rapi_rel_set_diff, 2}, + {"_duckdb_rapi_rel_set_intersect", (DL_FUNC) &_duckdb_rapi_rel_set_intersect, 2}, + {"_duckdb_rapi_rel_set_symdiff", (DL_FUNC) &_duckdb_rapi_rel_set_symdiff, 2}, + {"_duckdb_rapi_rel_sql", (DL_FUNC) &_duckdb_rapi_rel_sql, 2}, + {"_duckdb_rapi_rel_to_altrep", (DL_FUNC) &_duckdb_rapi_rel_to_altrep, 3}, + {"_duckdb_rapi_rel_to_csv", (DL_FUNC) &_duckdb_rapi_rel_to_csv, 3}, + {"_duckdb_rapi_rel_to_df", (DL_FUNC) &_duckdb_rapi_rel_to_df, 1}, + {"_duckdb_rapi_rel_to_parquet", (DL_FUNC) &_duckdb_rapi_rel_to_parquet, 3}, + {"_duckdb_rapi_rel_to_sql", (DL_FUNC) &_duckdb_rapi_rel_to_sql, 1}, + {"_duckdb_rapi_rel_to_table", (DL_FUNC) &_duckdb_rapi_rel_to_table, 4}, + {"_duckdb_rapi_rel_tostring", (DL_FUNC) &_duckdb_rapi_rel_tostring, 2}, + {"_duckdb_rapi_rel_union_all", (DL_FUNC) &_duckdb_rapi_rel_union_all, 2}, + {"_duckdb_rapi_reldf_aggregate", (DL_FUNC) &_duckdb_rapi_reldf_aggregate, 4}, + {"_duckdb_rapi_reldf_alias", (DL_FUNC) &_duckdb_rapi_reldf_alias, 2}, + {"_duckdb_rapi_reldf_distinct", (DL_FUNC) &_duckdb_rapi_reldf_distinct, 2}, + {"_duckdb_rapi_reldf_explain", (DL_FUNC) &_duckdb_rapi_reldf_explain, 4}, + {"_duckdb_rapi_reldf_filter", (DL_FUNC) &_duckdb_rapi_reldf_filter, 3}, + {"_duckdb_rapi_reldf_from_sql", (DL_FUNC) &_duckdb_rapi_reldf_from_sql, 2}, + {"_duckdb_rapi_reldf_from_table", (DL_FUNC) &_duckdb_rapi_reldf_from_table, 3}, + {"_duckdb_rapi_reldf_from_table_function", (DL_FUNC) &_duckdb_rapi_reldf_from_table_function, 4}, + {"_duckdb_rapi_reldf_insert", (DL_FUNC) &_duckdb_rapi_reldf_insert, 4}, + {"_duckdb_rapi_reldf_join", (DL_FUNC) &_duckdb_rapi_reldf_join, 6}, + {"_duckdb_rapi_reldf_limit", (DL_FUNC) &_duckdb_rapi_reldf_limit, 3}, + {"_duckdb_rapi_reldf_names", (DL_FUNC) &_duckdb_rapi_reldf_names, 2}, + {"_duckdb_rapi_reldf_order", (DL_FUNC) &_duckdb_rapi_reldf_order, 4}, + {"_duckdb_rapi_reldf_project", (DL_FUNC) &_duckdb_rapi_reldf_project, 3}, + {"_duckdb_rapi_reldf_set_alias", (DL_FUNC) &_duckdb_rapi_reldf_set_alias, 3}, + {"_duckdb_rapi_reldf_set_diff", (DL_FUNC) &_duckdb_rapi_reldf_set_diff, 3}, + {"_duckdb_rapi_reldf_set_intersect", (DL_FUNC) &_duckdb_rapi_reldf_set_intersect, 3}, + {"_duckdb_rapi_reldf_set_symdiff", (DL_FUNC) &_duckdb_rapi_reldf_set_symdiff, 3}, + {"_duckdb_rapi_reldf_to_csv", (DL_FUNC) &_duckdb_rapi_reldf_to_csv, 4}, + {"_duckdb_rapi_reldf_to_parquet", (DL_FUNC) &_duckdb_rapi_reldf_to_parquet, 4}, + {"_duckdb_rapi_reldf_to_table", (DL_FUNC) &_duckdb_rapi_reldf_to_table, 5}, + {"_duckdb_rapi_reldf_union_all", (DL_FUNC) &_duckdb_rapi_reldf_union_all, 3}, + {"_duckdb_rapi_release", (DL_FUNC) &_duckdb_rapi_release, 1}, + {"_duckdb_rapi_shutdown", (DL_FUNC) &_duckdb_rapi_shutdown, 1}, + {"_duckdb_rapi_startup", (DL_FUNC) &_duckdb_rapi_startup, 4}, + {"_duckdb_rapi_unlock", (DL_FUNC) &_duckdb_rapi_unlock, 1}, + {"_duckdb_rapi_unregister_arrow", (DL_FUNC) &_duckdb_rapi_unregister_arrow, 2}, + {"_duckdb_rapi_unregister_df", (DL_FUNC) &_duckdb_rapi_unregister_df, 2}, {NULL, NULL, 0} }; } diff --git a/src/include/reltoaltrep.hpp b/src/include/reltoaltrep.hpp index ee162a68a..f95fa3825 100644 --- a/src/include/reltoaltrep.hpp +++ b/src/include/reltoaltrep.hpp @@ -62,6 +62,6 @@ SEXP rapi_rel_from_altrep_df(SEXP df, bool strict, bool allow_materialized); SEXP rapi_rel_from_any_df(duckdb::conn_eptr_t con, SEXP df, bool allow_materialized); -SEXP rapi_rel_to_altrep2(duckdb::rel_extptr_t rel, duckdb::conn_eptr_t con, bool allow_materialization); +SEXP rapi_reldf_to_altrep(duckdb::rel_extptr_t rel, duckdb::conn_eptr_t con, bool allow_materialization); SEXP result_to_df(duckdb::unique_ptr res); diff --git a/src/relational2.cpp b/src/relational2.cpp index 16039a430..181c1c316 100644 --- a/src/relational2.cpp +++ b/src/relational2.cpp @@ -29,7 +29,7 @@ using namespace cpp11; // DuckDB Relations: names -[[cpp11::register]] SEXP rapi_rel_names2(data_frame df, duckdb::conn_eptr_t con) { +[[cpp11::register]] SEXP rapi_reldf_names(data_frame df, duckdb::conn_eptr_t con) { auto rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); auto ret = writable::strings(); @@ -39,21 +39,21 @@ using namespace cpp11; return (ret); } -[[cpp11::register]] std::string rapi_rel_alias2(data_frame df, duckdb::conn_eptr_t con) { +[[cpp11::register]] std::string rapi_reldf_alias(data_frame df, duckdb::conn_eptr_t con) { auto rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); return rel->rel->GetAlias(); } -[[cpp11::register]] SEXP rapi_rel_set_alias2(data_frame df, duckdb::conn_eptr_t con, std::string alias) { +[[cpp11::register]] SEXP rapi_reldf_set_alias(data_frame df, duckdb::conn_eptr_t con, std::string alias) { auto rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); cpp11::writable::list prot = {rel}; - return rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, rel->rel->Alias(alias)), con, true); + return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, rel->rel->Alias(alias)), con, true); } // DuckDB Relations: operators -[[cpp11::register]] SEXP rapi_rel_filter2(data_frame df, duckdb::conn_eptr_t con, list exprs) { +[[cpp11::register]] SEXP rapi_reldf_filter(data_frame df, duckdb::conn_eptr_t con, list exprs) { duckdb::unique_ptr filter_expr; if (exprs.size() == 0) { // nop warning("rel_filter without filter expressions has no effect"); @@ -73,10 +73,10 @@ using namespace cpp11; cpp11::writable::list prot = {rel}; - return rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, std::move(filter)), con, true); + return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(filter)), con, true); } -[[cpp11::register]] SEXP rapi_rel_project2(data_frame df, duckdb::conn_eptr_t con, list exprs) { +[[cpp11::register]] SEXP rapi_reldf_project(data_frame df, duckdb::conn_eptr_t con, list exprs) { if (exprs.size() == 0) { stop("expected projection expressions"); } @@ -96,10 +96,10 @@ using namespace cpp11; cpp11::writable::list prot = {rel}; - return rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, std::move(projection)), con, true); + return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(projection)), con, true); } -[[cpp11::register]] SEXP rapi_rel_aggregate2(data_frame df, duckdb::conn_eptr_t con, list groups, list aggregates) { +[[cpp11::register]] SEXP rapi_reldf_aggregate(data_frame df, duckdb::conn_eptr_t con, list groups, list aggregates) { vector> res_groups, res_aggregates; // TODO deal with empty groups @@ -127,10 +127,10 @@ using namespace cpp11; cpp11::writable::list prot = {rel}; - return rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, std::move(aggregate)), con, true); + return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(aggregate)), con, true); } -[[cpp11::register]] SEXP rapi_rel_order2(data_frame df, duckdb::conn_eptr_t con, list orders, r_vector ascending) { +[[cpp11::register]] SEXP rapi_reldf_order(data_frame df, duckdb::conn_eptr_t con, list orders, r_vector ascending) { vector res_orders; OrderType order_type; @@ -148,10 +148,10 @@ using namespace cpp11; cpp11::writable::list prot = {rel}; - return rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, std::move(order)), con, true); + return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(order)), con, true); } -[[cpp11::register]] SEXP rapi_rel_join2(data_frame left, data_frame right, duckdb::conn_eptr_t con, list conds, +[[cpp11::register]] SEXP rapi_reldf_join(data_frame left, data_frame right, duckdb::conn_eptr_t con, list conds, std::string join, std::string join_ref_type) { auto join_type = JoinType::INNER; auto ref_type = JoinRefType::REGULAR; @@ -189,10 +189,10 @@ using namespace cpp11; ref_type = JoinRefType::CROSS; } auto res = make_shared_ptr(rel_left->rel, rel_right->rel, ref_type); - auto df = rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, std::move(res)), con, true); + auto df = rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(res)), con, true); // if the user described filters, apply them on top of the cross product relation if (conds.size() > 0) { - return rapi_rel_filter2(df, con, conds); + return rapi_reldf_filter(df, con, conds); } return df; } @@ -208,10 +208,10 @@ using namespace cpp11; } auto res = make_shared_ptr(rel_left->rel, rel_right->rel, std::move(cond), join_type, ref_type); - return rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, std::move(res)), con, true); + return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(res)), con, true); } -[[cpp11::register]] SEXP rapi_rel_union_all2(data_frame left, data_frame right, duckdb::conn_eptr_t con) { +[[cpp11::register]] SEXP rapi_reldf_union_all(data_frame left, data_frame right, duckdb::conn_eptr_t con) { auto rel_left = cpp11::as_cpp>(rapi_rel_from_any_df(con, left, true)); auto rel_right = cpp11::as_cpp>(rapi_rel_from_any_df(con, right, true)); @@ -220,26 +220,26 @@ using namespace cpp11; auto setop = make_shared_ptr(rel_left->rel, rel_right->rel, SetOperationType::UNION); setop->setop_all = true; - return rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, std::move(setop)), con, true); + return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(setop)), con, true); } -[[cpp11::register]] SEXP rapi_rel_limit2(data_frame df, duckdb::conn_eptr_t con, int64_t n) { +[[cpp11::register]] SEXP rapi_reldf_limit(data_frame df, duckdb::conn_eptr_t con, int64_t n) { auto rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); cpp11::writable::list prot = {rel}; - return rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, make_shared_ptr(rel->rel, n, 0)), con, true); + return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, make_shared_ptr(rel->rel, n, 0)), con, true); } -[[cpp11::register]] SEXP rapi_rel_distinct2(data_frame df, duckdb::conn_eptr_t con) { +[[cpp11::register]] SEXP rapi_reldf_distinct(data_frame df, duckdb::conn_eptr_t con) { auto rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); cpp11::writable::list prot = {rel}; - return rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, make_shared_ptr(rel->rel)), con, true); + return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, make_shared_ptr(rel->rel)), con, true); } -[[cpp11::register]] SEXP rapi_rel_set_intersect2(data_frame left, data_frame right, duckdb::conn_eptr_t con) { +[[cpp11::register]] SEXP rapi_reldf_set_intersect(data_frame left, data_frame right, duckdb::conn_eptr_t con) { auto rel_left = cpp11::as_cpp>(rapi_rel_from_any_df(con, left, true)); auto rel_right = cpp11::as_cpp>(rapi_rel_from_any_df(con, right, true)); @@ -247,10 +247,10 @@ using namespace cpp11; cpp11::writable::list prot = {rel_left, rel_right}; - return rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, std::move(res)), con, true); + return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(res)), con, true); } -[[cpp11::register]] SEXP rapi_rel_set_diff2(data_frame left, data_frame right, duckdb::conn_eptr_t con) { +[[cpp11::register]] SEXP rapi_reldf_set_diff(data_frame left, data_frame right, duckdb::conn_eptr_t con) { auto rel_left = cpp11::as_cpp>(rapi_rel_from_any_df(con, left, true)); auto rel_right = cpp11::as_cpp>(rapi_rel_from_any_df(con, right, true)); @@ -258,10 +258,10 @@ using namespace cpp11; cpp11::writable::list prot = {rel_left, rel_right}; - return rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, std::move(res)), con, true); + return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(res)), con, true); } -[[cpp11::register]] SEXP rapi_rel_set_symdiff2(data_frame left, data_frame right, duckdb::conn_eptr_t con) { +[[cpp11::register]] SEXP rapi_reldf_set_symdiff(data_frame left, data_frame right, duckdb::conn_eptr_t con) { auto rel_left = cpp11::as_cpp>(rapi_rel_from_any_df(con, left, true)); auto rel_right = cpp11::as_cpp>(rapi_rel_from_any_df(con, right, true)); @@ -273,31 +273,31 @@ using namespace cpp11; cpp11::writable::list prot = {rel_left, rel_right}; - return rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, std::move(symdiff)), con, true); + return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(symdiff)), con, true); } // DuckDB Relations: conversion -[[cpp11::register]] SEXP rapi_rel_from_sql2(duckdb::conn_eptr_t con, const std::string sql) { +[[cpp11::register]] SEXP rapi_reldf_from_sql(duckdb::conn_eptr_t con, const std::string sql) { if (!con || !con.get() || !con->conn) { stop("rel_from_table: Invalid connection"); } auto rel = con->conn->RelationFromQuery(sql); cpp11::writable::list prot = {}; - return rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, std::move(rel)), con, true); + return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(rel)), con, true); } -[[cpp11::register]] SEXP rapi_rel_from_table2(duckdb::conn_eptr_t con, const std::string schema_name, +[[cpp11::register]] SEXP rapi_reldf_from_table(duckdb::conn_eptr_t con, const std::string schema_name, const std::string table_name) { if (!con || !con.get() || !con->conn) { stop("rel_from_table: Invalid connection"); } auto rel = con->conn->Table(schema_name, table_name); cpp11::writable::list prot = {}; - return rapi_rel_to_altrep2(make_external_prot("duckdb_relation", prot, std::move(rel)), con, true); + return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(rel)), con, true); } -[[cpp11::register]] SEXP rapi_rel_from_table_function2(duckdb::conn_eptr_t con, const std::string function_name, +[[cpp11::register]] SEXP rapi_reldf_from_table_function(duckdb::conn_eptr_t con, const std::string function_name, list positional_parameters_sexps, list named_parameters_sexps) { if (!con || !con.get() || !con->conn) { stop("rel_from_table_function: Invalid connection"); @@ -327,10 +327,10 @@ using namespace cpp11; } auto rel = con->conn->TableFunction(function_name, std::move(positional_parameters), std::move(named_parameters)); - return rapi_rel_to_altrep2(make_external("duckdb_relation", std::move(rel)), con, true); + return rapi_reldf_to_altrep(make_external("duckdb_relation", std::move(rel)), con, true); } -[[cpp11::register]] SEXP rapi_rel_explain2(data_frame df, duckdb::conn_eptr_t con, std::string type, std::string format) { +[[cpp11::register]] SEXP rapi_reldf_explain(data_frame df, duckdb::conn_eptr_t con, std::string type, std::string format) { auto type_enum = EnumUtil::FromString(type); auto format_enum = EnumUtil::FromString(format); @@ -339,22 +339,22 @@ using namespace cpp11; return result_to_df(rel->rel->Explain(type_enum, format_enum)); } -[[cpp11::register]] void rapi_rel_to_parquet2(data_frame df, duckdb::conn_eptr_t con, std::string file_name, list options_sexps) { +[[cpp11::register]] void rapi_reldf_to_parquet(data_frame df, duckdb::conn_eptr_t con, std::string file_name, list options_sexps) { auto rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); rel->rel->WriteParquet(file_name, ListToVectorOfValue(options_sexps)); } -[[cpp11::register]] void rapi_rel_to_csv2(data_frame df, duckdb::conn_eptr_t con, std::string file_name, list options_sexps) { +[[cpp11::register]] void rapi_reldf_to_csv(data_frame df, duckdb::conn_eptr_t con, std::string file_name, list options_sexps) { auto rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); rel->rel->WriteCSV(file_name, ListToVectorOfValue(options_sexps)); } -[[cpp11::register]] void rapi_rel_to_table2(data_frame df, duckdb::conn_eptr_t con, std::string schema_name, std::string table_name, bool temporary) { +[[cpp11::register]] void rapi_reldf_to_table(data_frame df, duckdb::conn_eptr_t con, std::string schema_name, std::string table_name, bool temporary) { auto rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); rel->rel->Create(schema_name, table_name, temporary); } -[[cpp11::register]] void rapi_rel_insert2(data_frame df, duckdb::conn_eptr_t con, std::string schema_name, std::string table_name) { +[[cpp11::register]] void rapi_reldf_insert(data_frame df, duckdb::conn_eptr_t con, std::string schema_name, std::string table_name) { auto rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); rel->rel->Insert(schema_name, table_name); } diff --git a/src/reltoaltrep.cpp b/src/reltoaltrep.cpp index 43d6a5581..c2d4a8cff 100644 --- a/src/reltoaltrep.cpp +++ b/src/reltoaltrep.cpp @@ -458,7 +458,7 @@ size_t DoubleToSize(double d) { } -SEXP rapi_rel_to_altrep2(duckdb::rel_extptr_t rel, duckdb::conn_eptr_t con, bool allow_materialization) { +SEXP rapi_reldf_to_altrep(duckdb::rel_extptr_t rel, duckdb::conn_eptr_t con, bool allow_materialization) { D_ASSERT(rel && rel->rel); auto drel = rel->rel; auto ncols = drel->Columns().size(); @@ -550,7 +550,7 @@ SEXP rapi_rel_to_altrep2(duckdb::rel_extptr_t rel, duckdb::conn_eptr_t con, bool auto res = R_altrep_data2(row_names); if (res == R_NilValue) { if (strict) { - cpp11::stop("rapi_rel_from_altrep_df: NULL in data2?"); + cpp11::stop("rapi_reldf_from_altrep_df: NULL in data?"); } else { return R_NilValue; } diff --git a/test-old.R b/test-old.R deleted file mode 100644 index 35a67e97b..000000000 --- a/test-old.R +++ /dev/null @@ -1,43 +0,0 @@ -drv <- duckdb::duckdb() -con <- DBI::dbConnect(drv) -df1 <- tibble::tibble(a = 1) - -"mutate" -#> [1] "mutate" -rel1 <- duckdb:::rel_from_df(con, df1) -"mutate" -#> [1] "mutate" -rel2 <- duckdb:::rel_project( - rel1, - list( - { - tmp_expr <- duckdb:::expr_reference("a") - duckdb:::expr_set_alias(tmp_expr, "a") - tmp_expr - }, - { - tmp_expr <- duckdb:::expr_constant(2) - duckdb:::expr_set_alias(tmp_expr, "b") - tmp_expr - } - ) -) -"filter" -#> [1] "filter" -rel3 <- duckdb:::rel_filter( - rel2, - list( - duckdb:::expr_comparison( - "==", - list( - duckdb:::expr_reference("b"), - duckdb:::expr_constant(2) - ) - ) - ) -) -rel2 -rel3 -duckdb:::rel_to_altrep(rel2) -rel2 -rel3 diff --git a/test.R b/test.R deleted file mode 100644 index d66dbd44a..000000000 --- a/test.R +++ /dev/null @@ -1,48 +0,0 @@ -drv <- duckdb::duckdb() -con <- DBI::dbConnect(drv) -df1 <- tibble::tibble(a = 1) - -df1 -"mutate" -rel2 <- duckdb:::rel_project2( - df1, - con, - list( - { - tmp_expr <- duckdb:::expr_reference("a") - duckdb:::expr_set_alias(tmp_expr, "a") - tmp_expr - }, - { - tmp_expr <- duckdb:::expr_constant(2) - duckdb:::expr_set_alias(tmp_expr, "b") - tmp_expr - } - ) -) - -df2 <- duckdb:::rel_to_altrep(rel2) -df1 -df2 -typeof(df1) -typeof(df2) - -"filter" -rel3 <- duckdb:::rel_filter2( - df2, - con, - list( - duckdb:::expr_comparison( - "==", - list( - duckdb:::expr_reference("b"), - duckdb:::expr_constant(2) - ) - ) - ) -) -rel2 -rel3 -duckdb:::rel_to_altrep(rel2) -rel2 -rel3 diff --git a/tests/testthat/_snaps/relational.md b/tests/testthat/_snaps/relational.md index dcbd2ed97..102990f90 100644 --- a/tests/testthat/_snaps/relational.md +++ b/tests/testthat/_snaps/relational.md @@ -113,7 +113,7 @@ # rel_explain() Code - writeLines(rel_explain_df(proj)[[2]]) + writeLines(reldf_explain_df(proj)[[]]) Output ┌───────────────────────────┐ │ R_DATAFRAME_SCAN │ @@ -128,14 +128,14 @@ --- Code - writeLines(rel_explain_df(proj, "analyze")[[2]]) + writeLines(reldf_explain_df(proj, "analyze")[[]]) Output Query profiling is disabled. Use 'PRAGMA enable_profiling;' to enable profiling! --- Code - writeLines(rel_explain_df(proj, "standard", "json")[[2]]) + writeLines(reldf_explain_df(proj, "standard", "json")[[]]) Output [ { @@ -152,7 +152,7 @@ --- Code - writeLines(rel_explain_df(proj, "analyze", "json")[[2]]) + writeLines(reldf_explain_df(proj, "analyze", "json")[[]]) Output { "result": "disabled" @@ -161,7 +161,7 @@ --- Code - writeLines(rel_explain_df(proj, "standard", "html")[[2]]) + writeLines(reldf_explain_df(proj, "standard", "html")[[]]) Output @@ -302,7 +302,7 @@ --- Code - writeLines(rel_explain_df(proj, "standard", "graphviz")[[2]]) + writeLines(reldf_explain_df(proj, "standard", "graphviz")[[]]) Output digraph G { diff --git a/tests/testthat/test-list.R b/tests/testthat/test-list.R index 5c3873ef6..a2d020194 100644 --- a/tests/testthat/test-list.R +++ b/tests/testthat/test-list.R @@ -39,6 +39,6 @@ test_that("rel_filter() handles LIST logical type", { rel1 <- rel_from_df(con, df1) rel2 <- rel_filter(rel1, list(expr_constant(TRUE))) - df2 <- rel_to_altrep(rel2) + df2 <- reldf_to_altrep(rel) expect_equal(df1$a, df2$a) }) diff --git a/tests/testthat/test-parquet.R b/tests/testthat/test-parquet.R index e7b54656b..c6fa7f32f 100644 --- a/tests/testthat/test-parquet.R +++ b/tests/testthat/test-parquet.R @@ -60,10 +60,10 @@ test_that("duckdb rel_to_parquet() allows multiple files (#1015)", { rel_to_parquet(rel1, tf1) tf2 <- tempfile(fileext = ".parquet") - rel2 <- rel_from_df(con, data.frame(a = 2)) - rel_to_parquet(rel2, tf2) + rel2 <- reldf_from_df(con, data.frame(a = )) + reldf_to_parquet(rel, tf2) - res_rel <- rel_from_table_function(con, "read_parquet", list(list(c(tf1, tf2)))) + res_rel <- reldf_from_table_function(con, "read_parquet", list(list(c(tf1, tf)))) res_df <- rel_to_altrep(res_rel) expect_identical(res_df, data.frame(a = c(1, 2))) diff --git a/tests/testthat/test-readonly.R b/tests/testthat/test-readonly.R index ce536c234..674812ca3 100644 --- a/tests/testthat/test-readonly.R +++ b/tests/testthat/test-readonly.R @@ -76,6 +76,6 @@ test_that("read_only flag still throws error when table is attempted to be creat con <- dbConnect(duckdb(), db_path, read_only=TRUE) rel <- duckdb:::rel_from_df(con, mtcars) - expect_error(duckdb:::rel_sql(rel, "create table t2 as (SELECT cyl, disp FROM _ )")) + expect_error(duckdb:::reldf_sql(rel, "create table t as (SELECT cyl, disp FROM _ )")) dbDisconnect(con) }) diff --git a/tests/testthat/test-rel_api.R b/tests/testthat/test-rel_api.R index 357a09885..c61d7c67a 100644 --- a/tests/testthat/test-rel_api.R +++ b/tests/testthat/test-rel_api.R @@ -19,7 +19,7 @@ test_that("relational anti_join(join_by(a)) order-preserving", { df2 <- data.frame(a = 2:5, b = 2) "anti_join" - rel3 <- rel_from_df(con, df2, experimental = experimental) + rel3 <- reldf_from_df(con, df, experimental = experimental) "anti_join" rel4 <- rel_set_alias(rel3, "rhs") "anti_join" @@ -98,7 +98,7 @@ test_that("relational anti_join(join_by(a)) order-enforcing", { df2 <- data.frame(a = 2:5, b = 2) "anti_join" - rel3 <- rel_from_df(con, df2, experimental = experimental) + rel3 <- reldf_from_df(con, df, experimental = experimental) "anti_join" rel4 <- rel_set_alias(rel3, "rhs") "anti_join" @@ -177,7 +177,7 @@ test_that("relational arrange(a) order-preserving", { ) ) "arrange" - rel3 <- rel_order(rel2, list(expr_reference("a"), expr_reference("___row_number"))) + rel3 <- reldf_order(rel, list(expr_reference("a"), expr_reference("___row_number"))) "arrange" rel4 <- rel_project( rel3, @@ -244,7 +244,7 @@ test_that("relational arrange(g) order-preserving", { ) ) "arrange" - rel3 <- rel_order(rel2, list(expr_reference("g"), expr_reference("___row_number"))) + rel3 <- reldf_order(rel, list(expr_reference("g"), expr_reference("___row_number"))) "arrange" rel4 <- rel_project( rel3, @@ -567,7 +567,7 @@ test_that("relational count() order-preserving", { ) ) rel2 - out <- rel_to_altrep(rel2) + out <- reldf_to_altrep(rel) expect_identical( out, data.frame(n = 6L) @@ -860,7 +860,7 @@ test_that("relational count() order-enforcing", { ) ) "arrange" - rel3 <- rel_order(rel2, list(expr_reference("n"))) + rel3 <- reldf_order(rel, list(expr_reference("n"))) rel3 out <- rel_to_altrep(rel3) expect_identical( @@ -1720,7 +1720,7 @@ test_that("relational union_all(data.frame(a = 1L, b = 3, g = 2L)) %>% distinct( df2 <- data.frame(a = 1L, b = 3, g = 2L) "union_all" - rel2 <- rel_from_df(con, df2, experimental = experimental) + rel2 <- reldf_from_df(con, df, experimental = experimental) "union_all" rel3 <- rel_project( rel1, @@ -1905,7 +1905,7 @@ test_that("relational union_all(data.frame(a = 1L, b = 3, g = 2L)) %>% distinct( ) ) rel12 - out <- rel_to_altrep(rel12) + out <- reldf_to_altrep(rel1) expect_identical( out, data.frame(g = 1:3) @@ -1925,7 +1925,7 @@ test_that("relational union_all(data.frame(a = 1L, b = 4, g = 2L)) %>% distinct( df2 <- data.frame(a = 1L, b = 4, g = 2L) "union_all" - rel2 <- rel_from_df(con, df2, experimental = experimental) + rel2 <- reldf_from_df(con, df, experimental = experimental) "union_all" rel3 <- rel_project( rel1, @@ -2110,7 +2110,7 @@ test_that("relational union_all(data.frame(a = 1L, b = 4, g = 2L)) %>% distinct( ) ) rel12 - out <- rel_to_altrep(rel12) + out <- reldf_to_altrep(rel1) expect_identical( out, data.frame(g = 1:3) @@ -2130,7 +2130,7 @@ test_that("relational union_all(data.frame(a = 1L, b = 5, g = 2L)) %>% distinct( df2 <- data.frame(a = 1L, b = 5, g = 2L) "union_all" - rel2 <- rel_from_df(con, df2, experimental = experimental) + rel2 <- reldf_from_df(con, df, experimental = experimental) "union_all" rel3 <- rel_project( rel1, @@ -2315,7 +2315,7 @@ test_that("relational union_all(data.frame(a = 1L, b = 5, g = 2L)) %>% distinct( ) ) rel12 - out <- rel_to_altrep(rel12) + out <- reldf_to_altrep(rel1) expect_identical( out, data.frame(g = 1:3) @@ -2335,7 +2335,7 @@ test_that("relational union_all(data.frame(a = 1L, b = 6, g = 2L)) %>% distinct( df2 <- data.frame(a = 1L, b = 6, g = 2L) "union_all" - rel2 <- rel_from_df(con, df2, experimental = experimental) + rel2 <- reldf_from_df(con, df, experimental = experimental) "union_all" rel3 <- rel_project( rel1, @@ -2520,7 +2520,7 @@ test_that("relational union_all(data.frame(a = 1L, b = 6, g = 2L)) %>% distinct( ) ) rel12 - out <- rel_to_altrep(rel12) + out <- reldf_to_altrep(rel1) expect_identical( out, data.frame(g = 1:3) @@ -2540,7 +2540,7 @@ test_that("relational union_all(data.frame(a = 1L, b = 7, g = 2L)) %>% distinct( df2 <- data.frame(a = 1L, b = 7, g = 2L) "union_all" - rel2 <- rel_from_df(con, df2, experimental = experimental) + rel2 <- reldf_from_df(con, df, experimental = experimental) "union_all" rel3 <- rel_project( rel1, @@ -2725,7 +2725,7 @@ test_that("relational union_all(data.frame(a = 1L, b = 7, g = 2L)) %>% distinct( ) ) rel12 - out <- rel_to_altrep(rel12) + out <- reldf_to_altrep(rel1) expect_identical( out, data.frame(g = 1:3) @@ -2904,7 +2904,7 @@ test_that("relational distinct(a) order-enforcing", { ) ) "distinct" - rel3 <- rel_distinct(rel2) + rel3 <- reldf_distinct(rel) "arrange" rel4 <- rel_order(rel3, list(expr_reference("a"))) rel4 @@ -2942,7 +2942,7 @@ test_that("relational distinct(a, b) order-enforcing", { ) ) "distinct" - rel3 <- rel_distinct(rel2) + rel3 <- reldf_distinct(rel) "arrange" rel4 <- rel_order(rel3, list(expr_reference("a"), expr_reference("b"))) rel4 @@ -2975,7 +2975,7 @@ test_that("relational distinct(b, b) order-enforcing", { ) ) "distinct" - rel3 <- rel_distinct(rel2) + rel3 <- reldf_distinct(rel) "arrange" rel4 <- rel_order(rel3, list(expr_reference("b"))) rel4 @@ -3008,7 +3008,7 @@ test_that("relational distinct(g) order-enforcing", { ) ) "distinct" - rel3 <- rel_distinct(rel2) + rel3 <- reldf_distinct(rel) "arrange" rel4 <- rel_order(rel3, list(expr_reference("g"))) rel4 @@ -3032,9 +3032,9 @@ test_that("relational union_all(data.frame(a = 1L, b = 3, g = 2L)) %>% distinct( df2 <- data.frame(a = 1L, b = 3, g = 2L) "union_all" - rel2 <- rel_from_df(con, df2, experimental = experimental) + rel2 <- reldf_from_df(con, df, experimental = experimental) "union_all" - rel3 <- rel_union_all(rel1, rel2) + rel3 <- reldf_union_all(rel1, rel) "distinct" rel4 <- rel_project( rel3, @@ -3071,9 +3071,9 @@ test_that("relational union_all(data.frame(a = 1L, b = 4, g = 2L)) %>% distinct( df2 <- data.frame(a = 1L, b = 4, g = 2L) "union_all" - rel2 <- rel_from_df(con, df2, experimental = experimental) + rel2 <- reldf_from_df(con, df, experimental = experimental) "union_all" - rel3 <- rel_union_all(rel1, rel2) + rel3 <- reldf_union_all(rel1, rel) "distinct" rel4 <- rel_project( rel3, @@ -3110,9 +3110,9 @@ test_that("relational union_all(data.frame(a = 1L, b = 5, g = 2L)) %>% distinct( df2 <- data.frame(a = 1L, b = 5, g = 2L) "union_all" - rel2 <- rel_from_df(con, df2, experimental = experimental) + rel2 <- reldf_from_df(con, df, experimental = experimental) "union_all" - rel3 <- rel_union_all(rel1, rel2) + rel3 <- reldf_union_all(rel1, rel) "distinct" rel4 <- rel_project( rel3, @@ -3149,9 +3149,9 @@ test_that("relational union_all(data.frame(a = 1L, b = 6, g = 2L)) %>% distinct( df2 <- data.frame(a = 1L, b = 6, g = 2L) "union_all" - rel2 <- rel_from_df(con, df2, experimental = experimental) + rel2 <- reldf_from_df(con, df, experimental = experimental) "union_all" - rel3 <- rel_union_all(rel1, rel2) + rel3 <- reldf_union_all(rel1, rel) "distinct" rel4 <- rel_project( rel3, @@ -3188,9 +3188,9 @@ test_that("relational union_all(data.frame(a = 1L, b = 7, g = 2L)) %>% distinct( df2 <- data.frame(a = 1L, b = 7, g = 2L) "union_all" - rel2 <- rel_from_df(con, df2, experimental = experimental) + rel2 <- reldf_from_df(con, df, experimental = experimental) "union_all" - rel3 <- rel_union_all(rel1, rel2) + rel3 <- reldf_union_all(rel1, rel) "distinct" rel4 <- rel_project( rel3, @@ -4071,7 +4071,7 @@ test_that("relational full_join(join_by(a)) order-preserving", { df2 <- data.frame(a = 2:5, b = 2) "full_join" - rel3 <- rel_from_df(con, df2, experimental = experimental) + rel3 <- reldf_from_df(con, df, experimental = experimental) "full_join" rel4 <- rel_set_alias(rel3, "rhs") "full_join" @@ -4212,7 +4212,7 @@ test_that("relational full_join(join_by(a)) order-enforcing", { df2 <- data.frame(a = 2:5, b = 2) "full_join" - rel3 <- rel_from_df(con, df2, experimental = experimental) + rel3 <- reldf_from_df(con, df, experimental = experimental) "full_join" rel4 <- rel_set_alias(rel3, "rhs") "full_join" @@ -4311,7 +4311,7 @@ test_that("relational inner_join(join_by(a)) order-preserving", { df2 <- data.frame(a = 2:5, b = 2) "inner_join" - rel3 <- rel_from_df(con, df2, experimental = experimental) + rel3 <- reldf_from_df(con, df, experimental = experimental) "inner_join" rel4 <- rel_set_alias(rel3, "rhs") "inner_join" @@ -4452,7 +4452,7 @@ test_that("relational inner_join(join_by(a)) order-enforcing", { df2 <- data.frame(a = 2:5, b = 2) "inner_join" - rel3 <- rel_from_df(con, df2, experimental = experimental) + rel3 <- reldf_from_df(con, df, experimental = experimental) "inner_join" rel4 <- rel_set_alias(rel3, "rhs") "inner_join" @@ -4550,7 +4550,7 @@ test_that("relational intersect() order-preserving", { df2 <- data.frame(a = 2:5, b = 2) "semi_join" - rel3 <- rel_from_df(con, df2, experimental = experimental) + rel3 <- reldf_from_df(con, df, experimental = experimental) "semi_join" rel4 <- rel_set_alias(rel3, "rhs") "semi_join" @@ -4720,9 +4720,9 @@ test_that("relational intersect() order-enforcing", { df2 <- data.frame(a = 2:5, b = 2) "intersect" - rel2 <- rel_from_df(con, df2, experimental = experimental) + rel2 <- reldf_from_df(con, df, experimental = experimental) "intersect" - rel3 <- rel_set_intersect(rel1, rel2) + rel3 <- reldf_set_intersect(rel1, rel) "arrange" rel4 <- rel_order(rel3, list(expr_reference("a"), expr_reference("b"))) rel4 @@ -4754,7 +4754,7 @@ test_that("relational left_join(join_by(a)) order-preserving", { df2 <- data.frame(a = 2:5, b = 2) "left_join" - rel3 <- rel_from_df(con, df2, experimental = experimental) + rel3 <- reldf_from_df(con, df, experimental = experimental) "left_join" rel4 <- rel_set_alias(rel3, "rhs") "left_join" @@ -4895,7 +4895,7 @@ test_that("relational left_join(join_by(a)) order-enforcing", { df2 <- data.frame(a = 2:5, b = 2) "left_join" - rel3 <- rel_from_df(con, df2, experimental = experimental) + rel3 <- reldf_from_df(con, df, experimental = experimental) "left_join" rel4 <- rel_set_alias(rel3, "rhs") "left_join" @@ -5040,7 +5040,7 @@ test_that("relational mutate(a + 1) order-preserving", { ) ) rel2 - out <- rel_to_altrep(rel2) + out <- reldf_to_altrep(rel) expect_identical( out, data.frame( @@ -5219,7 +5219,7 @@ test_that("relational mutate(c = a + 1) order-preserving", { ) ) rel2 - out <- rel_to_altrep(rel2) + out <- reldf_to_altrep(rel) expect_identical( out, data.frame( @@ -5278,7 +5278,7 @@ test_that("relational mutate(`if` = a + 1) order-preserving", { ) ) rel2 - out <- rel_to_altrep(rel2) + out <- reldf_to_altrep(rel) expect_identical( out, data.frame( @@ -5328,7 +5328,7 @@ test_that("relational mutate(sum(a)) order-preserving", { ) ) rel2 - out <- rel_to_altrep(rel2) + out <- reldf_to_altrep(rel) expect_identical( out, data.frame( @@ -5487,7 +5487,7 @@ test_that("relational mutate(mean(a)) order-preserving", { ) ) rel2 - out <- rel_to_altrep(rel2) + out <- reldf_to_altrep(rel) expect_identical( out, data.frame( @@ -5646,7 +5646,7 @@ test_that("relational mutate(sd(a)) order-preserving", { ) ) rel2 - out <- rel_to_altrep(rel2) + out <- reldf_to_altrep(rel) expect_identical( out, data.frame( @@ -5815,7 +5815,7 @@ test_that("relational mutate(lag(a)) order-preserving", { ) ) rel2 - out <- rel_to_altrep(rel2) + out <- reldf_to_altrep(rel) expect_identical( out, data.frame( @@ -5994,7 +5994,7 @@ test_that("relational mutate(lead(a)) order-preserving", { ) ) rel2 - out <- rel_to_altrep(rel2) + out <- reldf_to_altrep(rel) expect_identical( out, data.frame( @@ -6173,7 +6173,7 @@ test_that("relational mutate(lag(a, 2)) order-preserving", { ) ) rel2 - out <- rel_to_altrep(rel2) + out <- reldf_to_altrep(rel) expect_identical( out, data.frame( @@ -6352,7 +6352,7 @@ test_that("relational mutate(lead(a, 2)) order-preserving", { ) ) rel2 - out <- rel_to_altrep(rel2) + out <- reldf_to_altrep(rel) expect_identical( out, data.frame( @@ -6531,7 +6531,7 @@ test_that("relational mutate(lag(a, 4)) order-preserving", { ) ) rel2 - out <- rel_to_altrep(rel2) + out <- reldf_to_altrep(rel) expect_identical( out, data.frame( @@ -6710,7 +6710,7 @@ test_that("relational mutate(lead(a, 4)) order-preserving", { ) ) rel2 - out <- rel_to_altrep(rel2) + out <- reldf_to_altrep(rel) expect_identical( out, data.frame( @@ -6893,7 +6893,7 @@ test_that("relational mutate(lag(a, default = 0)) order-preserving", { ) ) rel2 - out <- rel_to_altrep(rel2) + out <- reldf_to_altrep(rel) expect_identical( out, data.frame( @@ -7080,7 +7080,7 @@ test_that("relational mutate(lead(a, default = 1000)) order-preserving", { ) ) rel2 - out <- rel_to_altrep(rel2) + out <- reldf_to_altrep(rel) expect_identical( out, data.frame( @@ -7253,7 +7253,7 @@ test_that("relational mutate(min(a)) order-preserving", { ) ) rel2 - out <- rel_to_altrep(rel2) + out <- reldf_to_altrep(rel) expect_identical( out, data.frame( @@ -7412,7 +7412,7 @@ test_that("relational mutate(max(a)) order-preserving", { ) ) rel2 - out <- rel_to_altrep(rel2) + out <- reldf_to_altrep(rel) expect_identical( out, data.frame( @@ -7571,7 +7571,7 @@ test_that("relational mutate(first(a)) order-preserving", { ) ) rel2 - out <- rel_to_altrep(rel2) + out <- reldf_to_altrep(rel) expect_identical( out, data.frame( @@ -7730,7 +7730,7 @@ test_that("relational mutate(last(a)) order-preserving", { ) ) rel2 - out <- rel_to_altrep(rel2) + out <- reldf_to_altrep(rel) expect_identical( out, data.frame( @@ -7905,7 +7905,7 @@ test_that("relational mutate(nth(a, 2)) order-preserving", { ) ) rel2 - out <- rel_to_altrep(rel2) + out <- reldf_to_altrep(rel) expect_identical( out, data.frame( @@ -8086,7 +8086,7 @@ test_that("relational mutate(a / b) order-preserving", { ) ) rel2 - out <- rel_to_altrep(rel2) + out <- reldf_to_altrep(rel) expect_identical( out, data.frame( @@ -8968,7 +8968,7 @@ test_that("relational mutate(d = a %in% NA_real_) order-preserving", { ) ) rel2 - out <- rel_to_altrep(rel2) + out <- reldf_to_altrep(rel) expect_identical( out, data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L), d = FALSE) @@ -9016,7 +9016,7 @@ test_that("relational mutate(d = a %in% NULL) order-preserving", { ) ) rel2 - out <- rel_to_altrep(rel2) + out <- reldf_to_altrep(rel) expect_identical( out, data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L), d = FALSE) @@ -9064,7 +9064,7 @@ test_that("relational mutate(d = a %in% integer()) order-preserving", { ) ) rel2 - out <- rel_to_altrep(rel2) + out <- reldf_to_altrep(rel) expect_identical( out, data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L), d = FALSE) @@ -9280,7 +9280,7 @@ test_that("relational mutate(d = row_number()) order-preserving", { ) ) rel2 - out <- rel_to_altrep(rel2) + out <- reldf_to_altrep(rel) expect_identical( out, data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L), d = 1:6) @@ -9438,7 +9438,7 @@ test_that("relational mutate(c = .data$b) order-preserving", { ) ) rel2 - out <- rel_to_altrep(rel2) + out <- reldf_to_altrep(rel) expect_identical( out, data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L), c = 2) @@ -9483,7 +9483,7 @@ test_that("relational mutate(d = NA) order-preserving", { ) ) rel2 - out <- rel_to_altrep(rel2) + out <- reldf_to_altrep(rel) expect_identical( out, data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L), d = NA) @@ -9531,7 +9531,7 @@ test_that("relational mutate(d = NA_integer_) order-preserving", { ) ) rel2 - out <- rel_to_altrep(rel2) + out <- reldf_to_altrep(rel) expect_identical( out, data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L), d = NA_integer_) @@ -9579,7 +9579,7 @@ test_that("relational mutate(d = NA_real_) order-preserving", { ) ) rel2 - out <- rel_to_altrep(rel2) + out <- reldf_to_altrep(rel) expect_identical( out, data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L), d = NA_real_) @@ -9627,7 +9627,7 @@ test_that("relational mutate(d = NA_character_) order-preserving", { ) ) rel2 - out <- rel_to_altrep(rel2) + out <- reldf_to_altrep(rel) expect_identical( out, data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L), d = NA_character_) @@ -9702,7 +9702,7 @@ test_that("relational mutate(d = if_else(a > 1, \"ok\", NA)) order-preserving", ) ) rel2 - out <- rel_to_altrep(rel2) + out <- reldf_to_altrep(rel) expect_identical( out, data.frame( @@ -9732,7 +9732,7 @@ test_that("relational mutate() order-enforcing", { list(expr_reference("a"), expr_reference("b"), expr_reference("g")) ) rel2 - out <- rel_to_altrep(rel2) + out <- reldf_to_altrep(rel) expect_identical( out, data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L)) @@ -13712,7 +13712,7 @@ test_that("relational relocate(g) order-preserving", { ) ) rel2 - out <- rel_to_altrep(rel2) + out <- reldf_to_altrep(rel) expect_identical( out, data.frame(g = c(1L, 2L, 2L, 3L, 3L, 3L), a = seq(1, 6, by = 1), b = 2) @@ -13751,7 +13751,7 @@ test_that("relational relocate(a) order-preserving", { ) ) rel2 - out <- rel_to_altrep(rel2) + out <- reldf_to_altrep(rel) expect_identical( out, data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L)) @@ -13790,7 +13790,7 @@ test_that("relational relocate(g, .before = b) order-preserving", { ) ) rel2 - out <- rel_to_altrep(rel2) + out <- reldf_to_altrep(rel) expect_identical( out, data.frame(a = seq(1, 6, by = 1), g = c(1L, 2L, 2L, 3L, 3L, 3L), b = 2) @@ -13829,7 +13829,7 @@ test_that("relational relocate(a:b, .after = g) order-preserving", { ) ) rel2 - out <- rel_to_altrep(rel2) + out <- reldf_to_altrep(rel) expect_identical( out, data.frame(g = c(1L, 2L, 2L, 3L, 3L, 3L), a = seq(1, 6, by = 1), b = 2) @@ -14048,7 +14048,7 @@ test_that("relational rename() order-preserving", { ) ) rel2 - out <- rel_to_altrep(rel2) + out <- reldf_to_altrep(rel) expect_identical( out, data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L)) @@ -14087,7 +14087,7 @@ test_that("relational rename(c = a) order-preserving", { ) ) rel2 - out <- rel_to_altrep(rel2) + out <- reldf_to_altrep(rel) expect_identical( out, data.frame(c = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L)) @@ -14204,7 +14204,7 @@ test_that("relational right_join(join_by(a)) order-preserving", { df2 <- data.frame(a = 2:5, b = 2) "right_join" - rel3 <- rel_from_df(con, df2, experimental = experimental) + rel3 <- reldf_from_df(con, df, experimental = experimental) "right_join" rel4 <- rel_set_alias(rel3, "rhs") "right_join" @@ -14344,7 +14344,7 @@ test_that("relational right_join(join_by(a)) order-enforcing", { df2 <- data.frame(a = 2:5, b = 2) "right_join" - rel3 <- rel_from_df(con, df2, experimental = experimental) + rel3 <- reldf_from_df(con, df, experimental = experimental) "right_join" rel4 <- rel_set_alias(rel3, "rhs") "right_join" @@ -14446,7 +14446,7 @@ test_that("relational select(a) order-preserving", { ) ) rel2 - out <- rel_to_altrep(rel2) + out <- reldf_to_altrep(rel) expect_identical( out, data.frame(a = seq(1, 6, by = 1)) @@ -14480,7 +14480,7 @@ test_that("relational select(-g) order-preserving", { ) ) rel2 - out <- rel_to_altrep(rel2) + out <- reldf_to_altrep(rel) expect_identical( out, data.frame(a = seq(1, 6, by = 1), b = 2) @@ -14519,7 +14519,7 @@ test_that("relational select(everything()) order-preserving", { ) ) rel2 - out <- rel_to_altrep(rel2) + out <- reldf_to_altrep(rel) expect_identical( out, data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L)) @@ -14550,7 +14550,7 @@ test_that("relational select(a) order-enforcing", { ) ) "arrange" - rel3 <- rel_order(rel2, list(expr_reference("a"))) + rel3 <- reldf_order(rel, list(expr_reference("a"))) rel3 out <- rel_to_altrep(rel3) expect_identical( @@ -14586,7 +14586,7 @@ test_that("relational select(-g) order-enforcing", { ) ) "arrange" - rel3 <- rel_order(rel2, list(expr_reference("a"), expr_reference("b"))) + rel3 <- reldf_order(rel, list(expr_reference("a"), expr_reference("b"))) rel3 out <- rel_to_altrep(rel3) expect_identical( @@ -14659,7 +14659,7 @@ test_that("relational semi_join(join_by(a)) order-preserving", { df2 <- data.frame(a = 2:5, b = 2) "semi_join" - rel3 <- rel_from_df(con, df2, experimental = experimental) + rel3 <- reldf_from_df(con, df, experimental = experimental) "semi_join" rel4 <- rel_set_alias(rel3, "rhs") "semi_join" @@ -14738,7 +14738,7 @@ test_that("relational semi_join(join_by(a)) order-enforcing", { df2 <- data.frame(a = 2:5, b = 2) "semi_join" - rel3 <- rel_from_df(con, df2, experimental = experimental) + rel3 <- reldf_from_df(con, df, experimental = experimental) "semi_join" rel4 <- rel_set_alias(rel3, "rhs") "semi_join" @@ -14780,7 +14780,7 @@ test_that("relational setdiff() order-preserving", { df2 <- data.frame(a = 2:5, b = 2) "anti_join" - rel3 <- rel_from_df(con, df2, experimental = experimental) + rel3 <- reldf_from_df(con, df, experimental = experimental) "anti_join" rel4 <- rel_set_alias(rel3, "rhs") "anti_join" @@ -14950,9 +14950,9 @@ test_that("relational setdiff() order-enforcing", { df2 <- data.frame(a = 2:5, b = 2) "setdiff" - rel2 <- rel_from_df(con, df2, experimental = experimental) + rel2 <- reldf_from_df(con, df, experimental = experimental) "setdiff" - rel3 <- rel_set_diff(rel1, rel2) + rel3 <- reldf_set_diff(rel1, rel) "arrange" rel4 <- rel_order(rel3, list(expr_reference("a"), expr_reference("b"))) rel4 @@ -14988,7 +14988,7 @@ test_that("relational summarise(c = mean(a)) order-preserving", { ) ) "summarise" - rel3 <- rel_distinct(rel2) + rel3 <- reldf_distinct(rel) rel3 out <- rel_to_altrep(rel3) expect_identical( @@ -15182,7 +15182,7 @@ test_that("relational summarise(c = 1) order-preserving", { ) ) "summarise" - rel3 <- rel_distinct(rel2) + rel3 <- reldf_distinct(rel) rel3 out <- rel_to_altrep(rel3) expect_identical( @@ -15398,7 +15398,7 @@ test_that("relational summarise(n = n(), n = n() + 1L) order-preserving", { ) ) "summarise" - rel3 <- rel_distinct(rel2) + rel3 <- reldf_distinct(rel) rel3 out <- rel_to_altrep(rel3) expect_identical( @@ -15432,7 +15432,7 @@ test_that("relational summarise(c = mean(a)) order-enforcing", { ) ) "summarise" - rel3 <- rel_distinct(rel2) + rel3 <- reldf_distinct(rel) "arrange" rel4 <- rel_order(rel3, list(expr_reference("c"))) rel4 @@ -15466,7 +15466,7 @@ test_that("relational summarise(c = mean(a), .by = b) order-enforcing", { ) ) "arrange" - rel3 <- rel_order(rel2, list(expr_reference("b"), expr_reference("c"))) + rel3 <- reldf_order(rel, list(expr_reference("b"), expr_reference("c"))) rel3 out <- rel_to_altrep(rel3) expect_identical( @@ -15498,7 +15498,7 @@ test_that("relational summarise(c = mean(a), .by = g) order-enforcing", { ) ) "arrange" - rel3 <- rel_order(rel2, list(expr_reference("g"), expr_reference("c"))) + rel3 <- reldf_order(rel, list(expr_reference("g"), expr_reference("c"))) rel3 out <- rel_to_altrep(rel3) expect_identical( @@ -15534,7 +15534,7 @@ test_that("relational summarise(c = 1) order-enforcing", { ) ) "summarise" - rel3 <- rel_distinct(rel2) + rel3 <- reldf_distinct(rel) "arrange" rel4 <- rel_order(rel3, list(expr_reference("c"))) rel4 @@ -15572,7 +15572,7 @@ test_that("relational summarise(c = 1, .by = g) order-enforcing", { ) ) "arrange" - rel3 <- rel_order(rel2, list(expr_reference("g"), expr_reference("c"))) + rel3 <- reldf_order(rel, list(expr_reference("g"), expr_reference("c"))) rel3 out <- rel_to_altrep(rel3) expect_identical( @@ -15615,7 +15615,7 @@ test_that("relational summarise(n = n(), n = n() + 1L, .by = g) order-enforcing" ) ) "arrange" - rel3 <- rel_order(rel2, list(expr_reference("g"), expr_reference("n"))) + rel3 <- reldf_order(rel, list(expr_reference("g"), expr_reference("n"))) rel3 out <- rel_to_altrep(rel3) expect_identical( @@ -15658,7 +15658,7 @@ test_that("relational summarise(n = n(), n = n() + 1L) order-enforcing", { ) ) "summarise" - rel3 <- rel_distinct(rel2) + rel3 <- reldf_distinct(rel) "arrange" rel4 <- rel_order(rel3, list(expr_reference("n"))) rel4 @@ -15689,7 +15689,7 @@ test_that("relational symdiff() order-preserving", { df2 <- data.frame(a = 2:5, b = 2) "anti_join" - rel3 <- rel_from_df(con, df2, experimental = experimental) + rel3 <- reldf_from_df(con, df, experimental = experimental) "anti_join" rel4 <- rel_set_alias(rel3, "rhs") "anti_join" @@ -15946,9 +15946,9 @@ test_that("relational symdiff() order-enforcing", { df2 <- data.frame(a = 2:5, b = 2) "symdiff" - rel2 <- rel_from_df(con, df2, experimental = experimental) + rel2 <- reldf_from_df(con, df, experimental = experimental) "symdiff" - rel3 <- rel_set_symdiff(rel1, rel2) + rel3 <- reldf_set_symdiff(rel1, rel) "arrange" rel4 <- rel_order(rel3, list(expr_reference("a"), expr_reference("b"))) rel4 @@ -15985,7 +15985,7 @@ test_that("relational tally() order-preserving", { ) ) "summarise" - rel3 <- rel_distinct(rel2) + rel3 <- reldf_distinct(rel) rel3 out <- rel_to_altrep(rel3) expect_identical( @@ -16020,7 +16020,7 @@ test_that("relational tally() order-enforcing", { ) ) "summarise" - rel3 <- rel_distinct(rel2) + rel3 <- reldf_distinct(rel) "arrange" rel4 <- rel_order(rel3, list(expr_reference("n"))) rel4 @@ -16065,7 +16065,7 @@ test_that("relational transmute(c = a + 1) order-preserving", { ) ) rel2 - out <- rel_to_altrep(rel2) + out <- reldf_to_altrep(rel) expect_identical( out, data.frame(c = seq(2, 7, by = 1)) @@ -16094,7 +16094,7 @@ test_that("relational transmute(row = a) order-preserving", { ) ) rel2 - out <- rel_to_altrep(rel2) + out <- reldf_to_altrep(rel) expect_identical( out, data.frame(row = seq(1, 6, by = 1)) @@ -16135,7 +16135,7 @@ test_that("relational transmute(c = a + 1) order-enforcing", { ) ) "arrange" - rel3 <- rel_order(rel2, list(expr_reference("c"))) + rel3 <- reldf_order(rel, list(expr_reference("c"))) rel3 out <- rel_to_altrep(rel3) expect_identical( @@ -16166,7 +16166,7 @@ test_that("relational transmute(row = a) order-enforcing", { ) ) "arrange" - rel3 <- rel_order(rel2, list(expr_reference("row"))) + rel3 <- reldf_order(rel, list(expr_reference("row"))) rel3 out <- rel_to_altrep(rel3) expect_identical( @@ -16190,7 +16190,7 @@ test_that("relational union() order-preserving", { df2 <- data.frame(a = 2:5, b = 2) "union_all" - rel2 <- rel_from_df(con, df2, experimental = experimental) + rel2 <- reldf_from_df(con, df, experimental = experimental) "union_all" rel3 <- rel_project( rel1, @@ -16370,7 +16370,7 @@ test_that("relational union() order-preserving", { ) ) rel12 - out <- rel_to_altrep(rel12) + out <- reldf_to_altrep(rel1) expect_identical( out, data.frame(a = 1:5, b = 2) @@ -16392,9 +16392,9 @@ test_that("relational union() order-enforcing", { df2 <- data.frame(a = 2:5, b = 2) "union_all" - rel2 <- rel_from_df(con, df2, experimental = experimental) + rel2 <- reldf_from_df(con, df, experimental = experimental) "union_all" - rel3 <- rel_union_all(rel1, rel2) + rel3 <- reldf_union_all(rel1, rel) "distinct" rel4 <- rel_distinct(rel3) "arrange" @@ -16422,7 +16422,7 @@ test_that("relational union_all() order-preserving", { df2 <- data.frame(a = 2:5, b = 2) "union_all" - rel2 <- rel_from_df(con, df2, experimental = experimental) + rel2 <- reldf_from_df(con, df, experimental = experimental) "union_all" rel3 <- rel_project( rel1, @@ -16529,9 +16529,9 @@ test_that("relational union_all() order-enforcing", { df2 <- data.frame(a = 2:5, b = 2) "union_all" - rel2 <- rel_from_df(con, df2, experimental = experimental) + rel2 <- reldf_from_df(con, df, experimental = experimental) "union_all" - rel3 <- rel_union_all(rel1, rel2) + rel3 <- reldf_union_all(rel1, rel) "arrange" rel4 <- rel_order(rel3, list(expr_reference("a"), expr_reference("b"))) rel4 diff --git a/tests/testthat/test-rel_api2.R b/tests/testthat/test-rel_api2.R index 686b06468..618abf871 100644 --- a/tests/testthat/test-rel_api2.R +++ b/tests/testthat/test-rel_api2.R @@ -8,12 +8,12 @@ test_that("relational anti_join(join_by(a)) order-enforcing 2", { ) df1 <- data.frame(a = 1:4, b = 2) "anti_join" - df2 <- rel_set_alias2(df1, con, "lhs") + df2 <- reldf_set_alias(df1, con, "lhs") df3 <- data.frame(a = 2:5, b = 2) "anti_join" - df4 <- rel_set_alias2(df3, con, "rhs") + df4 <- reldf_set_alias(df3, con, "rhs") "anti_join" - df5 <- rel_join2( + df5 <- reldf_join( df2, df4, con, @@ -23,7 +23,7 @@ test_that("relational anti_join(join_by(a)) order-enforcing 2", { "anti" ) "anti_join" - df6 <- rel_order2(df5, con, list(expr_reference("a"), expr_reference("b"))) + df6 <- reldf_order(df5, con, list(expr_reference("a"), expr_reference("b"))) df6 expect_identical( df6, @@ -42,12 +42,12 @@ test_that("relational anti_join(join_by(a)) order-enforcing 2", { ) df1 <- data.frame(a = 1:4, b = 2) "anti_join" - df2 <- rel_set_alias2(df1, con, "lhs") + df2 <- reldf_set_alias(df1, con, "lhs") df3 <- data.frame(a = 2:5, b = 2) "anti_join" - df4 <- rel_set_alias2(df3, con, "rhs") + df4 <- reldf_set_alias(df3, con, "rhs") "anti_join" - df5 <- rel_join2( + df5 <- reldf_join( df2, df4, con, @@ -57,7 +57,7 @@ test_that("relational anti_join(join_by(a)) order-enforcing 2", { "anti" ) "arrange" - df6 <- rel_order2(df5, con, list(expr_reference("a"), expr_reference("b"))) + df6 <- reldf_order(df5, con, list(expr_reference("a"), expr_reference("b"))) df6 expect_identical( df6, @@ -74,7 +74,7 @@ test_that("relational arrange(a) order-preserving 2", { df1 <- data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L)) "arrange" - df2 <- rel_project2( + df2 <- reldf_project( df1, con, list( @@ -101,9 +101,9 @@ test_that("relational arrange(a) order-preserving 2", { ) ) "arrange" - df3 <- rel_order2(df2, con, list(expr_reference2("a"), expr_reference2("___row_number"))) + df3 <- reldf_order(df2, con, list(expr_reference2("a"), expr_reference2("___row_number"))) "arrange" - df4 <- rel_project2( + df4 <- reldf_project( df3, con, list( @@ -139,7 +139,7 @@ test_that("relational arrange(g) order-enforcing 2", { df1 <- data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L)) "arrange" - df2 <- rel_project2( + df2 <- reldf_project( df1, con, list( @@ -166,9 +166,9 @@ test_that("relational arrange(g) order-enforcing 2", { ) ) "arrange" - df3 <- rel_order2(df2, con, list(expr_reference("g"), expr_reference("___row_number"))) + df3 <- reldf_order(df2, con, list(expr_reference("g"), expr_reference("___row_number"))) "arrange" - df4 <- rel_project2( + df4 <- reldf_project( df3, con, list( @@ -204,7 +204,7 @@ test_that("relational arrange() order-enforcing 2", { df1 <- data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L)) "arrange" - df2 <- rel_order2( + df2 <- reldf_order( df1, con, list(expr_reference("a"), expr_reference("b"), expr_reference("g")) @@ -224,7 +224,7 @@ test_that("relational arrange(a) order-enforcing 2", { df1 <- data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L)) "arrange" - df2 <- rel_order2( + df2 <- reldf_order( df1, con, list(expr_reference("a"), expr_reference("b"), expr_reference("g")) @@ -293,7 +293,7 @@ test_that("relational arrange(a, g) order-enforcing 2", { experimental <- FALSE df1 <- data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L)) - df2 <- rel_order2( + df2 <- reldf_order( df1, con, list(expr_reference("a"), expr_reference("b"), expr_reference("g")) @@ -314,7 +314,7 @@ test_that("relational count() order-preserving 2", { df1 <- data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L)) "count" - df2 <- rel_aggregate2( + df2 <- reldf_aggregate( df1, con, groups = list(), @@ -342,7 +342,7 @@ test_that("relational count(a) order-preserving 2", { df1 <- data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L)) "count" - df2 <- rel_aggregate2( + df2 <- reldf_aggregate( df1, con, groups = list( @@ -361,7 +361,7 @@ test_that("relational count(a) order-preserving 2", { ) ) "count" - df3 <- rel_order2( + df3 <- reldf_order( df2, con, list( @@ -388,7 +388,7 @@ test_that("relational count(b) order-preserving 2", { df1 <- data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L)) "count" - df2 <- rel_aggregate2( + df2 <- reldf_aggregate( df1, con, groups = list( @@ -407,7 +407,7 @@ test_that("relational count(b) order-preserving 2", { ) ) "count" - df3 <- rel_order2( + df3 <- reldf_order( df2, con, list( @@ -433,7 +433,7 @@ test_that("relational distinct() order-preserving 2", { df1 <- data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L)) "distinct" - df2 <- rel_project2( + df2 <- reldf_project( df1, con, list( @@ -460,7 +460,7 @@ test_that("relational distinct() order-preserving 2", { ) ) "distinct" - df3 <- rel_project2( + df3 <- reldf_project( df2, con, list( @@ -510,7 +510,7 @@ test_that("relational distinct() order-preserving 2", { ) ) "distinct" - df4 <- rel_filter2( + df4 <- reldf_filter( df3, con, list( @@ -528,9 +528,9 @@ test_that("relational distinct() order-preserving 2", { ) ) "distinct" - df5 <- rel_order2(df4, con, list(expr_reference("___row_number"))) + df5 <- reldf_order(df4, con, list(expr_reference("___row_number"))) "distinct" - df6 <- rel_project2( + df6 <- reldf_project( df5, con, list( @@ -566,7 +566,7 @@ test_that("relational distinct(a) order-preserving 2", { df1 <- data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L)) "distinct" - df2 <- rel_project2( + df2 <- reldf_project( df1, con, list( @@ -593,7 +593,7 @@ test_that("relational distinct(a) order-preserving 2", { ) ) "distinct" - df3 <- rel_project2( + df3 <- reldf_project( df2, con, list( @@ -623,7 +623,7 @@ test_that("relational distinct(a) order-preserving 2", { ) ) "distinct" - df4 <- rel_filter2( + df4 <- reldf_filter( df3, con, list( @@ -641,9 +641,9 @@ test_that("relational distinct(a) order-preserving 2", { ) ) "distinct" - df5 <- rel_order2(df4, con, list(expr_reference("___row_number"))) + df5 <- reldf_order(df4, con, list(expr_reference("___row_number"))) "distinct" - df6 <- rel_project2( + df6 <- reldf_project( df5, con, list( @@ -669,7 +669,7 @@ test_that("relational union_all(data.frame(a = 1L, b = 3, g = 2L)) %>% distinct( df1 <- data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L)) "union_all" - df2 <- rel_project2( + df2 <- reldf_project( df1, con, list( @@ -705,7 +705,7 @@ test_that("relational union_all(data.frame(a = 1L, b = 3, g = 2L)) %>% distinct( ) ) "union_all" - df3 <- rel_project2( + df3 <- reldf_project( df2, con, list( @@ -741,15 +741,15 @@ test_that("relational union_all(data.frame(a = 1L, b = 3, g = 2L)) %>% distinct( ) ) "union_all" - df4 <- rel_union_all2(df2, df3, con) + df4 <- reldf_union_all(df2, df3, con) "union_all" - df5 <- rel_order2( + df5 <- reldf_order( df4, con, list(expr_reference("___row_number_x"), expr_reference("___row_number_y")) ) "union_all" - df6 <- rel_project2( + df6 <- reldf_project( df5, con, list( @@ -771,7 +771,7 @@ test_that("relational union_all(data.frame(a = 1L, b = 3, g = 2L)) %>% distinct( ) ) "distinct" - df7 <- rel_project2( + df7 <- reldf_project( df6, con, list( @@ -798,7 +798,7 @@ test_that("relational union_all(data.frame(a = 1L, b = 3, g = 2L)) %>% distinct( ) ) "distinct" - df8 <- rel_project2( + df8 <- reldf_project( df7, con, list( @@ -828,7 +828,7 @@ test_that("relational union_all(data.frame(a = 1L, b = 3, g = 2L)) %>% distinct( ) ) "distinct" - df9 <- rel_filter2( + df9 <- reldf_filter( df8, con, list( @@ -846,9 +846,9 @@ test_that("relational union_all(data.frame(a = 1L, b = 3, g = 2L)) %>% distinct( ) ) "distinct" - df10 <- rel_order2(df9, con, list(expr_reference("___row_number"))) + df10 <- reldf_order(df9, con, list(expr_reference("___row_number"))) "distinct" - df11 <- rel_project2( + df11 <- reldf_project( df10, con, list( @@ -874,7 +874,7 @@ test_that("relational filter(a == 1) order-enforcing", { df1 <- data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L)) "filter" - df2 <- rel_filter2( + df2 <- reldf_filter( df1, con, list( @@ -892,7 +892,7 @@ test_that("relational filter(a == 1) order-enforcing", { ) ) "arrange" - df3 <- rel_order2( + df3 <- reldf_order( df2, con, list(expr_reference("a"), expr_reference("b"), expr_reference("g")) @@ -916,7 +916,7 @@ test_that("relational filter(a %in% 2:3 & g == 2) order-enforcing", { df1 <- data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L)) "filter" - df2 <- rel_filter2( + df2 <- reldf_filter( df1, con, list( @@ -976,7 +976,7 @@ test_that("relational filter(a %in% 2:3 & g == 2) order-enforcing", { ) ) "arrange" - df3 <- rel_order2( + df3 <- reldf_order( df2, con, list(expr_reference("a"), expr_reference("b"), expr_reference("g")) @@ -997,7 +997,7 @@ test_that("relational summarise(c = mean(a)) order-enforcing", { df1 <- data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L)) "summarise" - df2 <- rel_aggregate2( + df2 <- reldf_aggregate( df1, con, groups = list(), @@ -1010,9 +1010,9 @@ test_that("relational summarise(c = mean(a)) order-enforcing", { ) ) "summarise" - df3 <- rel_distinct2(df2, con) + df3 <- reldf_distinct(df2, con) "arrange" - df4 <- rel_order2(df3, con, list(expr_reference("c"))) + df4 <- reldf_order(df3, con, list(expr_reference("c"))) expect_identical( df4, data.frame(c = 3.5) @@ -1028,7 +1028,7 @@ test_that("relational summarise(c = mean(a), .by = b) order-enforcing", { df1 <- data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L)) "summarise" - df2 <- rel_aggregate2( + df2 <- reldf_aggregate( df1, con, groups = list(expr_reference("b")), @@ -1041,7 +1041,7 @@ test_that("relational summarise(c = mean(a), .by = b) order-enforcing", { ) ) "arrange" - df3 <- rel_order2(df2, con, list(expr_reference("b"), expr_reference("c"))) + df3 <- reldf_order(df2, con, list(expr_reference("b"), expr_reference("c"))) expect_identical( df3, data.frame(b = 2, c = 3.5) @@ -1057,7 +1057,7 @@ test_that("relational summarise(c = mean(a), .by = g) order-enforcing", { df1 <- data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L)) "summarise" - df2 <- rel_aggregate2( + df2 <- reldf_aggregate( df1, con, groups = list(expr_reference("g")), @@ -1070,7 +1070,7 @@ test_that("relational summarise(c = mean(a), .by = g) order-enforcing", { ) ) "arrange" - df3 <- rel_order2(df2, con, list(expr_reference("g"), expr_reference("c"))) + df3 <- reldf_order(df2, con, list(expr_reference("g"), expr_reference("c"))) expect_identical( df3, data.frame(g = 1:3, c = c(1, 2.5, 5)) @@ -1087,9 +1087,9 @@ test_that("relational intersect() order-enforcing", { df2 <- data.frame(a = 2:5, b = 2) "intersect" - df3 <- rel_set_intersect2(df1, df2, con) + df3 <- reldf_set_intersect(df1, df2, con) "arrange" - df4 <- rel_order2(df3, con, list(expr_reference("a"), expr_reference("b"))) + df4 <- reldf_order(df3, con, list(expr_reference("a"), expr_reference("b"))) expect_identical( df4, data.frame(a = 2:4, b = 2) @@ -1106,9 +1106,9 @@ test_that("relational setdiff() order-enforcing", { df2 <- data.frame(a = 2:5, b = 2) "setdiff" - df3 <- rel_set_diff2(df1, df2, con) + df3 <- reldf_set_diff(df1, df2, con) "arrange" - df4 <- rel_order2(df3, con, list(expr_reference("a"), expr_reference("b"))) + df4 <- reldf_order(df3, con, list(expr_reference("a"), expr_reference("b"))) expect_identical( df4, data.frame(a = 1L, b = 2) @@ -1125,9 +1125,9 @@ test_that("relational symdiff() order-enforcing", { df2 <- data.frame(a = 2:5, b = 2) "symdiff" - df3 <- rel_set_symdiff2(df1, df2, con) + df3 <- reldf_set_symdiff(df1, df2, con) "arrange" - df4 <- rel_order2(df3, con, list(expr_reference("a"), expr_reference("b"))) + df4 <- reldf_order(df3, con, list(expr_reference("a"), expr_reference("b"))) expect_identical( df4, data.frame(a = c(1L, 5L), b = 2) diff --git a/tests/testthat/test-relational.R b/tests/testthat/test-relational.R index c59ae1bb9..035d70235 100644 --- a/tests/testthat/test-relational.R +++ b/tests/testthat/test-relational.R @@ -146,7 +146,7 @@ test_that("we can cast R strings to DuckDB strings", { # many rounds yay df2 <- df for (i in 1:10) { - df2 <- as.data.frame.duckdb_relation(rel_from_df(con, df2)) + df2 <- as.data.frame.duckdb_relation(reldf_from_df(con, df)) expect_equivalent(df, df2) } @@ -154,7 +154,7 @@ test_that("we can cast R strings to DuckDB strings", { for (i in 1:10) { df2 <- as.data.frame( rel_sql( - rel_from_df(con, df2), + reldf_from_df(con, df), "SELECT s::string s FROM _" ) ) @@ -223,11 +223,11 @@ test_that("rel_order() sorts NAs last", { test_that("Inner join returns all inner relations", { dbExecute(con, "CREATE OR REPLACE MACRO eq(a, b) AS a = b") - left <- rel_from_df(con, data.frame(left_a = c(1, 2, 3), left_b = c(1, 1, 2))) + left <- reldf_from_df(con, data.frame(left_a = c(1, , 3), left_b = c(1, 1, 2))) right <- rel_from_df(con, data.frame(right_b = c(1, 3), right_c = c(4, 5))) cond <- list(expr_function("eq", list(expr_reference("left_b"), expr_reference("right_b")))) rel2 <- rel_join(left, right, cond, "inner") - rel_df <- rel_to_altrep(rel2) + reldf_df <- rel_to_altrep(rel) dim(rel_df) expected_result <- data.frame(left_a = c(1, 2), left_b = c(1, 1), right_b = c(1, 1), right_c = c(4, 4)) expect_equal(rel_df, expected_result) @@ -235,11 +235,11 @@ test_that("Inner join returns all inner relations", { test_that("Left join returns all left relations", { dbExecute(con, "CREATE OR REPLACE MACRO eq(a, b) AS a = b") - left <- rel_from_df(con, data.frame(left_a = c(1, 2, 3), left_b = c(1, 1, 2))) + left <- reldf_from_df(con, data.frame(left_a = c(1, , 3), left_b = c(1, 1, 2))) right <- rel_from_df(con, data.frame(right_b = c(1))) cond <- list(expr_function("eq", list(expr_reference("left_b"), expr_reference("right_b")))) rel2 <- rel_join(left, right, cond, "left") - rel_df <- rel_to_altrep(rel2) + reldf_df <- rel_to_altrep(rel) dim(rel_df) expected_result <- data.frame(left_a = c(1, 2, 3), left_b = c(1, 1, 2), right_b = c(1, 1, NA)) expect_equal(rel_df, expected_result) @@ -248,10 +248,10 @@ test_that("Left join returns all left relations", { test_that("Right join returns all right relations", { dbExecute(con, "CREATE OR REPLACE MACRO eq(a, b) AS a = b") left <- rel_from_df(con, data.frame(left_b = c(1))) - right <- rel_from_df(con, data.frame(right_a = c(1, 2, 3), right_b = c(1, 1, 2))) + right <- reldf_from_df(con, data.frame(right_a = c(1, , 3), right_b = c(1, 1, 2))) cond <- list(expr_function("eq", list(expr_reference("left_b"), expr_reference("right_b")))) rel2 <- rel_join(left, right, cond, "right") - rel_df <- rel_to_altrep(rel2) + reldf_df <- rel_to_altrep(rel) dim(rel_df) expected_result <- data.frame(left_b = c(1, 1, NA), right_a = c(1, 2, 3), right_b = c(1, 1, 2)) expect_equal(rel_df, expected_result) @@ -259,11 +259,11 @@ test_that("Right join returns all right relations", { test_that("Full join returns all outer relations", { dbExecute(con, "CREATE OR REPLACE MACRO eq(a, b) AS a = b") - left <- rel_from_df(con, data.frame(left_a = c(1, 2, 5), left_b = c(4, 5, 6))) - right <- rel_from_df(con, data.frame(right_a = c(1, 2, 3), right_b = c(1, 1, 2))) + left <- reldf_from_df(con, data.frame(left_a = c(1, , 5), left_b = c(4, 5, 6))) + right <- reldf_from_df(con, data.frame(right_a = c(1, , 3), right_b = c(1, 1, 2))) cond <- list(expr_function("eq", list(expr_reference("left_a"), expr_reference("right_a")))) rel2 <- rel_join(left, right, cond, "outer") - rel_df <- rel_to_altrep(rel2) + reldf_df <- rel_to_altrep(rel) expected_result <- data.frame( left_a = c(1, 2, 5, NA), @@ -278,7 +278,7 @@ test_that("Full join returns all outer relations", { }) test_that("cross join works", { - left <- rel_from_df(con, data.frame(left_a = c(1, 2, 3), left_b = c(1, 1, 2))) + left <- reldf_from_df(con, data.frame(left_a = c(1, , 3), left_b = c(1, 1, 2))) right <- rel_from_df(con, data.frame(right_a = c(1, 4, 5), right_b = c(7, 8, 9))) cross <- rel_join(left, right, list(), "cross") order_by <- rel_order(cross, list(expr_reference("right_a"), expr_reference("right_a"))) @@ -295,11 +295,11 @@ test_that("cross join works", { test_that("semi join works", { left <- rel_from_df(con, data.frame(left_b = c(1, 5, 6))) - right <- rel_from_df(con, data.frame(right_a = c(1, 2, 3), right_b = c(1, 1, 2))) + right <- reldf_from_df(con, data.frame(right_a = c(1, , 3), right_b = c(1, 1, 2))) cond <- list(expr_function("eq", list(expr_reference("left_b"), expr_reference("right_a")))) # select * from left semi join right on (left_b = right_a) rel2 <- rel_join(left, right, cond, "semi") - rel_df <- rel_to_altrep(rel2) + reldf_df <- rel_to_altrep(rel) dim(rel_df) expected_result <- data.frame(left_b = c(1)) expect_equal(rel_df, expected_result) @@ -308,18 +308,18 @@ test_that("semi join works", { test_that("anti join works", { left <- rel_from_df(con, data.frame(left_b = c(1, 5, 6))) - right <- rel_from_df(con, data.frame(right_a = c(1, 2, 3), right_b = c(1, 1, 2))) + right <- reldf_from_df(con, data.frame(right_a = c(1, , 3), right_b = c(1, 1, 2))) cond <- list(expr_function("eq", list(expr_reference("left_b"), expr_reference("right_a")))) # select * from left anti join right on (left_b = right_a) rel2 <- rel_join(left, right, cond, "anti") - rel_df <- rel_to_altrep(rel2) + reldf_df <- rel_to_altrep(rel) dim(rel_df) expected_result <- data.frame(left_b = c(5, 6)) expect_equal(rel_df, expected_result) }) test_that("Union all does not immediately materialize", { - test_df_a <- rel_from_df(con, data.frame(a = c("1", "2"), b = c("3", "4"))) + test_df_a <- reldf_from_df(con, data.frame(a = c("1", ""), b = c("3", "4"))) test_df_b <- rel_from_df(con, data.frame(a = c("5", "6"), b = c("7", "8"))) rel <- rel_union_all(test_df_a, test_df_b) rel_df <- rel_to_altrep(rel) @@ -329,7 +329,7 @@ test_that("Union all does not immediately materialize", { }) test_that("Union all has the correct values", { - test_df_a <- rel_from_df(con, data.frame(a = c("1", "2"), b = c("3", "4"))) + test_df_a <- reldf_from_df(con, data.frame(a = c("1", ""), b = c("3", "4"))) test_df_b <- rel_from_df(con, data.frame(a = c("5", "6"), b = c("7", "8"))) rel <- rel_union_all(test_df_a, test_df_b) order_by_rel <- rel_order(rel, list(expr_reference("a"), expr_reference("b"))) @@ -342,9 +342,9 @@ test_that("Union all has the correct values", { }) test_that("Union all keeps duplicates", { - test_df_a2 <- rel_from_df(con, data.frame(a = c("1", "2"), b = c("3", "4"))) - test_df_b2 <- rel_from_df(con, data.frame(a = c("1", "2"), b = c("3", "4"))) - rel <- rel_union_all(test_df_a2, test_df_b2) + test_df_a2 <- reldf_from_df(con, data.frame(a = c("1", ""), b = c("3", "4"))) + test_df_b2 <- reldf_from_df(con, data.frame(a = c("1", ""), b = c("3", "4"))) + rel <- reldf_union_all(test_df_a, test_df_b2) order_by_rel <- rel_order(rel, list(expr_reference("a"), expr_reference("b"))) rel_df <- rel_to_altrep(order_by_rel) dim(rel_df) @@ -355,11 +355,11 @@ test_that("Union all keeps duplicates", { test_that("Inner join returns all inner relations", { dbExecute(con, "CREATE OR REPLACE MACRO eq(a, b) AS a = b") - left <- rel_from_df(con, data.frame(left_a = c(1, 2, 3), left_b = c(1, 1, 2))) + left <- reldf_from_df(con, data.frame(left_a = c(1, , 3), left_b = c(1, 1, 2))) right <- rel_from_df(con, data.frame(right_b = c(1, 3), right_c = c(4, 5))) cond <- list(expr_function("eq", list(expr_reference("left_b"), expr_reference("right_b")))) rel2 <- rel_join(left, right, cond, "inner") - rel_df <- rel_to_altrep(rel2) + reldf_df <- rel_to_altrep(rel) dim(rel_df) expected_result <- data.frame(left_a = c(1, 2), left_b = c(1, 1), right_b = c(1, 1), right_c = c(4, 4)) expect_equal(rel_df, expected_result) @@ -367,10 +367,10 @@ test_that("Inner join returns all inner relations", { test_that("ASOF join works", { dbExecute(con, "CREATE OR REPLACE MACRO gte(a, b) AS a >= b") - test_df1 <- rel_from_df(con, data.frame(ts = c(1, 2, 3, 4, 5, 6, 7, 8, 9))) - test_df2 <- rel_from_df(con, data.frame(event_ts = c(1, 3, 6, 8), event_id = c(0, 1, 2, 3))) + test_df1 <- reldf_from_df(con, data.frame(ts = c(1, , 3, 4, 5, 6, 7, 8, 9))) + test_df2 <- reldf_from_df(con, data.frame(event_ts = c(1, 3, 6, 8), event_id = c(0, 1, , 3))) cond <- list(expr_function("gte", list(expr_reference("ts"), expr_reference("event_ts")))) - rel <- rel_join(test_df1, test_df2, cond, join_ref_type = "asof") + rel <- reldf_join(test_df1, test_df, cond, join_ref_type = "asof") rel_proj <- rel_project(rel, list(expr_reference("ts"), expr_reference("event_id"))) order <- rel_order(rel_proj, list(expr_reference("ts"))) rel_df <- rel_to_altrep(order) @@ -380,10 +380,10 @@ test_that("ASOF join works", { test_that("LEFT ASOF join works", { dbExecute(con, "CREATE OR REPLACE MACRO gte(a, b) AS a >= b") - test_df1 <- rel_from_df(con, data.frame(ts = c(0, 1, 2, 3, 4, 5, 6, 7, 8, 9))) - test_df2 <- rel_from_df(con, data.frame(event_ts = c(2, 4, 6, 8), event_id = c(0, 1, 2, 3))) + test_df1 <- reldf_from_df(con, data.frame(ts = c(0, 1, , 3, 4, 5, 6, 7, 8, 9))) + test_df2 <- reldf_from_df(con, data.frame(event_ts = c(, 4, 6, 8), event_id = c(0, 1, 2, 3))) cond <- list(expr_function("gte", list(expr_reference("ts"), expr_reference("event_ts")))) - rel <- rel_join(test_df1, test_df2, cond, join = "left", join_ref_type = "asof") + rel <- reldf_join(test_df1, test_df, cond, join = "left", join_ref_type = "asof") rel_proj <- rel_project(rel, list(expr_reference("ts"), expr_reference("event_ts"), expr_reference("event_id"))) order <- rel_order(rel_proj, list(expr_reference("ts"))) rel_df <- rel_to_altrep(order) @@ -392,9 +392,9 @@ test_that("LEFT ASOF join works", { }) test_that("Positional cross join works", { - test_df1 <- rel_from_df(con, data.frame(a = c(11, 12, 13), b = c(1, 2, 3))) - test_df2 <- rel_from_df(con, data.frame(c = c(11, 12), d = c(1, 2))) - rel <- rel_join(test_df1, test_df2, list(), join = "cross", join_ref_type = "positional") + test_df1 <- reldf_from_df(con, data.frame(a = c(11, 1, 13), b = c(1, 2, 3))) + test_df2 <- reldf_from_df(con, data.frame(c = c(11, 1), d = c(1, 2))) + rel <- reldf_join(test_df1, test_df, list(), join = "cross", join_ref_type = "positional") rel_df <- rel_to_altrep(rel) expected_result <- data.frame(a = c(11, 12, 13), b = c(1, 2, 3), c = c(11, 12, NA), d = c(1, 2, NA)) expect_equal(expected_result, rel_df) @@ -402,10 +402,10 @@ test_that("Positional cross join works", { test_that("regular positional join works", { dbExecute(con, "CREATE OR REPLACE MACRO eq(a, b) AS a = b") - test_df1 <- rel_from_df(con, data.frame(a = c(11, 12, 13), b = c(1, 2, 3))) - test_df2 <- rel_from_df(con, data.frame(c = c(11, 12, 14, 11), d = c(4, 5, 6, 8))) + test_df1 <- reldf_from_df(con, data.frame(a = c(11, 1, 13), b = c(1, 2, 3))) + test_df2 <- reldf_from_df(con, data.frame(c = c(11, 1, 14, 11), d = c(4, 5, 6, 8))) cond <- expr_function("eq", list(expr_reference("a"), expr_reference("c"))) - rel <- rel_join(test_df1, test_df2, list(cond), join_ref_type = "positional") + rel <- reldf_join(test_df1, test_df, list(cond), join_ref_type = "positional") rel_df <- rel_to_altrep(rel) expected_result <- data.frame(a = c(11, 12), b = c(1, 2), c = c(11, 12), d = c(4, 5)) expect_equal(expected_result, rel_df) @@ -413,27 +413,27 @@ test_that("regular positional join works", { test_that("Invalid asof join condition throws error", { dbExecute(con, "CREATE OR REPLACE MACRO neq(a, b) AS a <> b") - test_df1 <- rel_from_df(con, data.frame(ts = c(1, 2, 3, 4, 5, 6, 7, 8, 9))) - test_df2 <- rel_from_df(con, data.frame(begin = c(1, 3, 6, 8), value = c(0, 1, 2, 3))) + test_df1 <- reldf_from_df(con, data.frame(ts = c(1, , 3, 4, 5, 6, 7, 8, 9))) + test_df2 <- reldf_from_df(con, data.frame(begin = c(1, 3, 6, 8), value = c(0, 1, , 3))) cond <- list(expr_function("neq", list(expr_reference("ts"), expr_reference("begin")))) - expect_error(rel_join(test_df1, test_df2, cond, join_ref_type = "asof"), "Binder") + expect_error(reldf_join(test_df1, test_df, cond, join_ref_type = "asof"), "Binder") }) test_that("multiple inequality conditions for asof join throws error", { dbExecute(con, "CREATE OR REPLACE MACRO gte(a, b) AS a >= b") - test_df1 <- rel_from_df(con, data.frame(ts = c(1, 2, 3, 4, 5, 6, 7, 8, 9))) - test_df2 <- rel_from_df(con, data.frame(begin = c(1, 3, 6, 8), value = c(0, 1, 2, 3))) + test_df1 <- reldf_from_df(con, data.frame(ts = c(1, , 3, 4, 5, 6, 7, 8, 9))) + test_df2 <- reldf_from_df(con, data.frame(begin = c(1, 3, 6, 8), value = c(0, 1, , 3))) cond1 <- expr_function("gte", list(expr_reference("ts"), expr_reference("begin"))) cond2 <- expr_function("gte", list(expr_reference("ts"), expr_reference("value"))) conds <- list(cond1, cond2) - expect_error(rel_join(test_df1, test_df2, conds, join_ref_type = "asof"), "Binder") + expect_error(reldf_join(test_df1, test_df, conds, join_ref_type = "asof"), "Binder") }) test_that("Inequality joins work", { dbExecute(con, "CREATE OR REPLACE MACRO gte(a, b) AS a >= b") - timing_df <- rel_from_df(con, data.frame(ts = c(1, 2, 3, 4, 5, 6))) - events_df <- rel_from_df(con, data.frame(event_ts = c(1, 3, 6, 8), event_id = c(0, 1, 2, 3))) + timing_df <- reldf_from_df(con, data.frame(ts = c(1, , 3, 4, 5, 6))) + events_df <- reldf_from_df(con, data.frame(event_ts = c(1, 3, 6, 8), event_id = c(0, 1, , 3))) cond <- list(expr_function("gte", list(expr_reference("ts"), expr_reference("event_ts")))) rel <- rel_inner_join(timing_df, events_df, cond) rel_proj <- rel_project(rel, list(expr_reference("ts"), expr_reference("event_ts"))) @@ -447,8 +447,8 @@ test_that("Inequality joins work", { test_that("Inequality join works to perform between operation", { dbExecute(con, "CREATE OR REPLACE MACRO gt(a, b) AS a > b") dbExecute(con, "CREATE OR REPLACE MACRO lt(a, b) AS a < b") - timing_df <- rel_from_df(con, data.frame(ts = c(1, 2, 3, 4, 5, 6, 7, 8, 9))) - events_df <- rel_from_df(con, data.frame(event_ts = c(1, 3, 6, 8), event_id = c(0, 1, 2, 3))) + timing_df <- reldf_from_df(con, data.frame(ts = c(1, , 3, 4, 5, 6, 7, 8, 9))) + events_df <- reldf_from_df(con, data.frame(event_ts = c(1, 3, 6, 8), event_id = c(0, 1, , 3))) lead <- expr_function("lead", list(expr_reference("event_ts"))) window_lead <- expr_window(lead, offset_expr = expr_constant(1)) expr_set_alias(window_lead, "lead") @@ -467,24 +467,24 @@ test_that("Inequality join works to perform between operation", { # nobody should do this in reality. It's a pretty dumb idea test_that("we can union the same relation to itself", { - test_df_a2 <- rel_from_df(con, data.frame(a = c("1", "2"), b = c("3", "4"))) - rel <- rel_union_all(test_df_a2, test_df_a2) + test_df_a2 <- reldf_from_df(con, data.frame(a = c("1", ""), b = c("3", "4"))) + rel <- reldf_union_all(test_df_a, test_df_a2) rel_df <- rel_to_altrep(rel) expected_result <- data.frame(a = c("1", "2", "1", "2"), b = c("3", "4", "3", "4")) expect_equal(rel_df, expected_result) }) test_that("we throw an error when attempting to union all relations that are not compatible", { - test_df_a2 <- rel_from_df(con, data.frame(a = c("1", "2"), b = c("3", "4"))) - test_df_b2 <- rel_from_df(con, data.frame(a = c("1", "2"), b = c("3", "4"), c = c("5", "6"))) + test_df_a2 <- reldf_from_df(con, data.frame(a = c("1", ""), b = c("3", "4"))) + test_df_b2 <- reldf_from_df(con, data.frame(a = c("1", ""), b = c("3", "4"), c = c("5", "6"))) # The two data frames have different dimensions, therefore you get a binding error. - expect_error(rel_union_all(test_df_a2, test_df_b2), "Binder") + expect_error(reldf_union_all(test_df_a, test_df_b2), "Binder") }) test_that("A union with different column types casts to the richer type", { test_df_a1 <- rel_from_df(con, data.frame(a = c(1))) test_df_a2 <- rel_from_df(con, data.frame(a = c("1"))) - rel <- rel_union_all(test_df_a1, test_df_a2) + rel <- reldf_union_all(test_df_a1, test_df_a) res <- rapi_rel_to_df(rel) expected <- data.frame(a = c("1.0", "1")) expect_equal(class(res$a), class(expected$a)) @@ -493,7 +493,7 @@ test_that("A union with different column types casts to the richer type", { }) test_that("Set Intersect returns set intersection", { - test_df_a <- rel_from_df(con, data.frame(a = c(1, 2), b = c(3, 4))) + test_df_a <- reldf_from_df(con, data.frame(a = c(1, ), b = c(3, 4))) test_df_b <- rel_from_df(con, data.frame(a = c(1, 6), b = c(3, 8))) rel <- rel_set_intersect(test_df_a, test_df_b) ordered_rel <- rel_order(rel, list(expr_reference("a"))) @@ -513,14 +513,14 @@ test_that("Set intersect casts columns to the richer type", { expect_equal(class(df2$x), "numeric") out <- rel_set_intersect( rel_from_df(con, df1), - rel_from_df(con, df2) + reldf_from_df(con, df) ) out_df <- rapi_rel_to_df(out) expect_equal(class(out_df$x), "numeric") }) test_that("Set Diff returns the set difference", { - test_df_a <- rel_from_df(con, data.frame(a = c(1, 2), b = c(3, 4))) + test_df_a <- reldf_from_df(con, data.frame(a = c(1, ), b = c(3, 4))) test_df_b <- rel_from_df(con, data.frame(a = c(1, 6), b = c(3, 8))) rel <- rel_set_diff(test_df_a, test_df_b) rel_df <- rel_to_altrep(rel) @@ -531,7 +531,7 @@ test_that("Set Diff returns the set difference", { }) test_that("Symmetric difference returns the symmetric difference", { - test_df_a <- rel_from_df(con, data.frame(a = c(1, 2), b = c(3, 4))) + test_df_a <- reldf_from_df(con, data.frame(a = c(1, ), b = c(3, 4))) test_df_b <- rel_from_df(con, data.frame(a = c(1, 6), b = c(3, 8))) rel <- rel_set_symdiff(test_df_a, test_df_b) ordered_rel <- rel_order(rel, list(expr_reference("a"), expr_reference("b"))) @@ -543,7 +543,7 @@ test_that("Symmetric difference returns the symmetric difference", { }) test_that("rel aggregate with no groups but a sum over a column, sums the column", { - rel_a <- rel_from_df(con, data.frame(a = c(1, 2), b = c(3, 4))) + reldf_a <- rel_from_df(con, data.frame(a = c(1, ), b = c(3, 4))) aggrs <- list(sum = expr_function("sum", list(expr_reference("a")))) res <- rel_aggregate(rel_a, list(), aggrs) rel_df <- rel_to_altrep(res) @@ -552,7 +552,7 @@ test_that("rel aggregate with no groups but a sum over a column, sums the column }) test_that("rel aggregate with groups and aggregate function works", { - rel_a <- rel_from_df(con, data.frame(a = c(1, 2, 5, 5), b = c(3, 3, 4, 4))) + reldf_a <- rel_from_df(con, data.frame(a = c(1, , 5, 5), b = c(3, 3, 4, 4))) aggrs <- list(sum = expr_function("sum", list(expr_reference("a")))) rel_b <- rel_aggregate(rel_a, list(expr_reference("b")), aggrs) res <- rel_order(rel_b, list(expr_reference("b"))) @@ -563,7 +563,7 @@ test_that("rel aggregate with groups and aggregate function works", { test_that("Window sum expression function test works", { # select j, i, sum(i) over (partition by j) from a order by 1,2 - rel_a <- rel_from_df(con, data.frame(a = c(1:8), b = c(1, 1, 2, 2, 3, 3, 4, 4))) + reldf_a <- rel_from_df(con, data.frame(a = c(1:8), b = c(1, 1, , 2, 3, 3, 4, 4))) sum_func <- expr_function("sum", list(expr_reference("a"))) aggrs <- expr_window(sum_func, partitions = list(expr_reference("b"))) expr_set_alias(aggrs, "window_result") @@ -576,7 +576,7 @@ test_that("Window sum expression function test works", { test_that("Window count function works", { # select a, b, count(b) over (partition by a) from a order by a - rel_a <- rel_from_df(con, data.frame(a = c(1:8), b = c(1, 1, 2, 2, 3, 3, 4, 4))) + reldf_a <- rel_from_df(con, data.frame(a = c(1:8), b = c(1, 1, , 2, 3, 3, 4, 4))) count_func <- expr_function("count", list(expr_reference("a"))) count <- expr_window(count_func, partitions = list(expr_reference("b"))) expr_set_alias(count, "window_result") @@ -588,7 +588,7 @@ test_that("Window count function works", { test_that("Window avg function works", { # select a, b, avg(b) over (partition by a) from a order by a - rel_a <- rel_from_df(con, data.frame(a = c(1:8), b = c(1, 1, 2, 2, 3, 3, 4, 4))) + reldf_a <- rel_from_df(con, data.frame(a = c(1:8), b = c(1, 1, , 2, 3, 3, 4, 4))) avg_func <- expr_function("avg", list(expr_reference("a"))) avg_window <- expr_window(avg_func, partitions = list(expr_reference("b"))) expr_set_alias(avg_window, "window_result") @@ -601,7 +601,7 @@ test_that("Window avg function works", { test_that("Window sum with Partition, order, and window boundaries works", { # SUM(x) OVER (partition by b ROWS BETWEEN 3 PRECEDING AND CURRENT ROW) - rel_a <- rel_from_df(con, data.frame(a = c(1:8), b = c(1, 1, 1, 1, 2, 2, 2, 2))) + reldf_a <- rel_from_df(con, data.frame(a = c(1:8), b = c(1, 1, 1, 1, , 2, 2, 2))) partitions <- list(expr_reference("b")) order_by_a <- list(rel_order(rel_a, list(expr_reference("a")))) sum_func <- expr_function("sum", list(expr_reference("a"))) @@ -622,7 +622,7 @@ test_that("Window sum with Partition, order, and window boundaries works", { test_that("Window boundaries boundaries are CaSe INsenSItive", { # SUM(x) OVER (partition by b ROWS BETWEEN 3 PRECEDING AND CURRENT ROW) - rel_a <- rel_from_df(con, data.frame(a = c(1:8), b = c(1, 1, 1, 1, 2, 2, 2, 2))) + reldf_a <- rel_from_df(con, data.frame(a = c(1:8), b = c(1, 1, 1, 1, , 2, 2, 2))) partitions <- list(expr_reference("b")) order_by_a <- list(rel_order(rel_a, list(expr_reference("a")))) sum_func <- expr_function("sum", list(expr_reference("a"))) @@ -645,7 +645,7 @@ test_that("Window avg with a filter expression and partition works", { # select a, b, avg(a) FILTER (WHERE x % 2 = 0) over (partition by b) DBI::dbExecute(con, "CREATE OR REPLACE MACRO mod(a, b) as a % b") DBI::dbExecute(con, "CREATE OR REPLACE MACRO eq(a, b) as a = b") - rel_a <- rel_from_df(con, data.frame(a = c(1:8), b = c(1, 1, 2, 2, 3, 3, 4, 4))) + reldf_a <- rel_from_df(con, data.frame(a = c(1:8), b = c(1, 1, , 2, 3, 3, 4, 4))) partitions <- list(expr_reference("b")) mod_function <- expr_function("mod", list(expr_reference("a"), expr_constant(2))) zero <- expr_constant(0) @@ -662,7 +662,7 @@ test_that("Window avg with a filter expression and partition works", { test_that("Window lag function works as expected", { # select a, b, lag(a, 1) OVER () order by a - rel_a <- rel_from_df(con, data.frame(a = c(1:8), b = c(1, 1, 2, 2, 3, 3, 4, 4))) + reldf_a <- rel_from_df(con, data.frame(a = c(1:8), b = c(1, 1, , 2, 3, 3, 4, 4))) lag <- expr_function("lag", list(expr_reference("a"))) window_lag <- expr_window(lag, offset_expr = expr_constant(1)) expr_set_alias(window_lag, "lag") @@ -676,7 +676,7 @@ test_that("Window lag function works as expected", { test_that("function name for window is case insensitive", { # select a, b, lag(a, 1) OVER () order by a - rel_a <- rel_from_df(con, data.frame(a = c(1:8), b = c(1, 1, 2, 2, 3, 3, 4, 4))) + reldf_a <- rel_from_df(con, data.frame(a = c(1:8), b = c(1, 1, , 2, 3, 3, 4, 4))) lag <- expr_function("LAG", list(expr_reference("a"))) window_lag <- expr_window(lag, offset_expr = expr_constant(1)) expr_set_alias(window_lag, "lag") @@ -689,7 +689,7 @@ test_that("function name for window is case insensitive", { test_that("Window lead function works as expected", { # select a, b, lag(a, 1) OVER () order by a - rel_a <- rel_from_df(con, data.frame(a = c(1:8), b = c(1, 1, 2, 2, 3, 3, 4, 4))) + reldf_a <- rel_from_df(con, data.frame(a = c(1:8), b = c(1, 1, , 2, 3, 3, 4, 4))) lead <- expr_function("lead", list(expr_reference("a"))) window_lead <- expr_window(lead, offset_expr = expr_constant(1)) expr_set_alias(window_lead, "lead") @@ -702,7 +702,7 @@ test_that("Window lead function works as expected", { test_that("Window function with string aggregate works", { # select j, s, string_agg(s, '|') over (partition by b) from a order by j, s; - rel_a <- rel_from_df(con, data.frame(r = c(1, 2, 3, 4), a = c("hello", "Big", "world", "42"), b = c(1, 1, 2, 2))) + reldf_a <- rel_from_df(con, data.frame(r = c(1, , 3, 4), a = c("hello", "Big", "world", "42"), b = c(1, 1, 2, 2))) str_agg <- expr_function("string_agg", list(expr_reference("a"))) partitions <- list(expr_reference("b")) window_str_cat <- expr_window(str_agg, partitions = partitions) @@ -716,7 +716,7 @@ test_that("Window function with string aggregate works", { test_that("You can perform window functions on row_number", { # select a, b, row_number() OVER () from tmp order by a; - rel_a <- rel_from_df(con, data.frame(a = c(8:1), b = c(1, 1, 2, 2, 3, 3, 4, 4))) + reldf_a <- rel_from_df(con, data.frame(a = c(8:1), b = c(1, 1, , 2, 3, 3, 4, 4))) row_number <- expr_function("row_number", list()) window_function <- expr_window(row_number) expr_set_alias(window_function, "row_number") @@ -732,7 +732,7 @@ test_that("You can perform window functions on row_number", { # in dplyr min_rank = rank test_that("You can perform the window function min_rank", { # select rank() OVER (order by a) from t1 - rel_a <- rel_from_df(con, data.frame(a = c(1, 1, 2, 2, 2))) + reldf_a <- rel_from_df(con, data.frame(a = c(1, 1, , 2, 2))) rank_func <- expr_function("rank", list()) min_rank_window <- expr_window(rank_func, order_bys = list(expr_reference("a"))) expr_set_alias(min_rank_window, "window_result") @@ -744,7 +744,7 @@ test_that("You can perform the window function min_rank", { test_that("You can perform the window function dense_rank", { # select dense_rank() OVER (order by a) from t1; - rel_a <- rel_from_df(con, data.frame(a = c(1, 1, 2, 2, 2))) + reldf_a <- rel_from_df(con, data.frame(a = c(1, 1, , 2, 2))) dense_rank_fun <- expr_function("dense_rank", list()) min_rank_window <- expr_window(dense_rank_fun, order_bys = list(expr_reference("a"))) expr_set_alias(min_rank_window, "window_result") @@ -756,7 +756,7 @@ test_that("You can perform the window function dense_rank", { test_that("You can perform the window function cume_dist", { # select cume_dist() OVER (order by a) from t1; - rel_a <- rel_from_df(con, data.frame(a = c(1, 1, 2, 2, 2))) + reldf_a <- rel_from_df(con, data.frame(a = c(1, 1, , 2, 2))) cume_dist_func <- expr_function("cume_dist", list()) cume_dist_window <- expr_window(cume_dist_func, order_bys = list(expr_reference("a"))) expr_set_alias(cume_dist_window, "cume_dist") @@ -769,7 +769,7 @@ test_that("You can perform the window function cume_dist", { test_that("You can perform the window function percent rank", { # select percent_rank() OVER (order by a) from t1; - rel_a <- rel_from_df(con, data.frame(a = c(5, 1, 3, 2, 2))) + reldf_a <- rel_from_df(con, data.frame(a = c(5, 1, 3, , 2))) percent_rank_func <- expr_function("percent_rank", list()) percent_rank_wind <- expr_window(percent_rank_func, order_bys = list(expr_reference("a"))) expr_set_alias(percent_rank_wind, "percent_rank") @@ -783,7 +783,7 @@ test_that("You can perform the window function percent rank", { # with and without offsets test_that("R semantics for adding NaNs is respected", { dbExecute(con, "CREATE OR REPLACE MACRO eq(a, b) AS a = b") - test_df_a <- rel_from_df(con, data.frame(a = c(1, 2), b = c(3, 4))) + test_df_a <- reldf_from_df(con, data.frame(a = c(1, ), b = c(3, 4))) test_df_b <- rel_from_df(con, data.frame(c = c(NaN, 6), d = c(3, 8))) cond <- list(expr_function("eq", list(expr_reference("b"), expr_reference("d")))) rel_join <- rel_join(test_df_a, test_df_b, cond, "inner") @@ -803,20 +803,20 @@ test_that("R semantics for arithmetics sum function are respected", { test_that("anti joins for eq_na_matches works", { dbExecute(con, 'CREATE OR REPLACE MACRO "___eq_na_matches_na"(a, b) AS ((a IS NULL AND b IS NULL) OR (a = b))') - rel1 <- rel_from_df(con, data.frame(x = c(1, 1, 2, 3))) - rel2 <- rel_from_df(con, data.frame(y = c(2, 3, 3, 4))) + rel1 <- reldf_from_df(con, data.frame(x = c(1, 1, , 3))) + rel2 <- reldf_from_df(con, data.frame(y = c(, 3, 3, 4))) cond <- list(expr_function("___eq_na_matches_na", list(expr_reference("x"), expr_reference("y")))) - out <- rel_join(rel1, rel2, cond, "anti") + out <- reldf_join(rel1, rel, cond, "anti") res <- rel_to_altrep(out) expect_equal(res, data.frame(x = c(1, 1))) }) test_that("semi joins for eq_na_matches works", { dbExecute(con, 'CREATE OR REPLACE MACRO "___eq_na_matches_na"(a, b) AS ((a IS NULL AND b IS NULL) OR (a = b))') - rel1 <- rel_from_df(con, data.frame(x = c(1, 1, 2, 2))) - rel2 <- rel_from_df(con, data.frame(y = c(2, 2, 2, 2, 3, 3, 3))) + rel1 <- reldf_from_df(con, data.frame(x = c(1, 1, , 2))) + rel2 <- reldf_from_df(con, data.frame(y = c(, 2, 2, 2, 3, 3, 3))) cond <- list(expr_function("___eq_na_matches_na", list(expr_reference("x"), expr_reference("y")))) - out <- rel_join(rel1, rel2, cond, "semi") + out <- reldf_join(rel1, rel, cond, "semi") res <- rel_to_altrep(out) expect_equal(res, data.frame(x = c(2, 2))) }) @@ -860,27 +860,27 @@ test_that("rel_explain()", { proj <- rel_project(rel, exprs) expect_snapshot({ - writeLines(rel_explain_df(proj)[[2]]) + writeLines(reldf_explain_df(proj)[[]]) }) expect_snapshot({ - writeLines(rel_explain_df(proj, "analyze")[[2]]) + writeLines(reldf_explain_df(proj, "analyze")[[]]) }) expect_snapshot({ - writeLines(rel_explain_df(proj, "standard", "json")[[2]]) + writeLines(reldf_explain_df(proj, "standard", "json")[[]]) }) expect_snapshot({ - writeLines(rel_explain_df(proj, "analyze", "json")[[2]]) + writeLines(reldf_explain_df(proj, "analyze", "json")[[]]) }) expect_snapshot({ - writeLines(rel_explain_df(proj, "standard", "html")[[2]]) + writeLines(reldf_explain_df(proj, "standard", "html")[[]]) }) expect_snapshot({ - writeLines(rel_explain_df(proj, "standard", "graphviz")[[2]]) + writeLines(reldf_explain_df(proj, "standard", "graphviz")[[]]) }) }) @@ -896,13 +896,13 @@ test_that("rel_to_sql works for row_number", { tmp_expr }) ) - sql <- rel_to_sql(rel2) + sql <- reldf_to_sql(rel) sub_str_sql <- substr(sql, 0, 44) expect_equal(sub_str_sql, "SELECT row_number() OVER () AS ___row_number") }) test_that("rel_from_table_function works", { - rel <- rel_from_table_function(con, "generate_series", list(1L, 10L, 2L)) + rel <- reldf_from_table_function(con, "generate_series", list(1L, 10L, L)) df <- as.data.frame(rel) expect_equal(df$generate_series, c(1, 3, 5, 7, 9)) }) @@ -931,7 +931,7 @@ test_that("we don't crash with evaluation errors", { ) ) - ans <- rel_to_altrep(rel2) + ans <- reldf_to_altrep(rel) # This query is supposed to throw a runtime error. # If this succeeds, find a new query that throws a runtime error. @@ -962,7 +962,7 @@ test_that("we don't crash with evaluation errors", { ) ) - ans <- rel_to_altrep(rel2) + ans <- reldf_to_altrep(rel) # This query is supposed to throw a runtime error. # If this succeeds, find a new query that throws a runtime error. @@ -998,41 +998,41 @@ test_that("tethering", { ) ) - forbid <- rel_to_altrep(rel2, allow_materialization = FALSE) + forbid <- reldf_to_altrep(rel, allow_materialization = FALSE) expect_snapshot(error = TRUE, { nrow(forbid) }) - forbid_nrow <- rel_to_altrep(rel2, n_cells = 0) + forbid_nrow <- reldf_to_altrep(rel, n_cells = 0) expect_snapshot(error = TRUE, { nrow(forbid) }) - five_rows <- rel_to_altrep(rel2, n_rows = 5) + five_rows <- reldf_to_altrep(rel, n_rows = 5) expect_error(nrow(five_rows), NA) - four_rows <- rel_to_altrep(rel2, n_rows = 4) + four_rows <- reldf_to_altrep(rel, n_rows = 4) expect_snapshot(error = TRUE, { nrow(four_rows) }) - ten_cells <- rel_to_altrep(rel2, n_cells = 10) + ten_cells <- reldf_to_altrep(rel, n_cells = 10) expect_error(nrow(ten_cells), NA) - nine_cells <- rel_to_altrep(rel2, n_cells = 9) + nine_cells <- reldf_to_altrep(rel, n_cells = 9) expect_snapshot(error = TRUE, { nrow(nine_cells) }) - ok_both <- rel_to_altrep(rel2, n_rows = 5, n_cells = 10) + ok_both <- reldf_to_altrep(rel, n_rows = 5, n_cells = 10) expect_error(nrow(ok_both), NA) - bad_rows <- rel_to_altrep(rel2, n_rows = 4, n_cells = 10) + bad_rows <- reldf_to_altrep(rel, n_rows = 4, n_cells = 10) expect_snapshot(error = TRUE, { nrow(bad_rows) }) - bad_cells <- rel_to_altrep(rel2, n_rows = 5, n_cells = 9) + bad_cells <- reldf_to_altrep(rel, n_rows = 5, n_cells = 9) expect_snapshot(error = TRUE, { nrow(bad_cells) }) From 2eb6fe0447266c3489c0d1a1844e2e795be2b5f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Sat, 8 Mar 2025 17:48:19 +0100 Subject: [PATCH 56/69] Remove expr_reference2() --- R/relational.R | 28 ++++++---------------------- tests/testthat/test-rel_api2.R | 12 ++++++------ 2 files changed, 12 insertions(+), 28 deletions(-) diff --git a/R/relational.R b/R/relational.R index 4d5d72508..b005a6134 100644 --- a/R/relational.R +++ b/R/relational.R @@ -2,38 +2,22 @@ #' Create a column reference expression #' @param names the column name to be referenced, could be a list to refer to schema.table.column etc. -#' @param table the optional table name or a relation object to be referenced +#' @param table the optional table name or a relation object or relational data frame to be referenced +#' @param con the optional connection #' @return a column reference expression #' @noRd #' @examples #' col_ref_expr <- expr_reference("some_column_name") #' col_ref_expr2 <- expr_reference("some_column_name", "some_table_name") -expr_reference <- function(names, table = NULL) { +expr_reference <- function(names, table = NULL, con = NULL) { if (inherits(table, "duckdb_relation")) { names <- c(rel_alias(table), names) - } - if (is.character(table) && !identical(table, "")) { - names <- c(table, names) - } - rethrow_rapi_expr_reference(names) -} - - -#' Create a column reference expression -#' @param names the column name to be referenced, could be a list to refer to schema.table.column etc. -#' @param table the optional table name or a relation object to be referenced -#' @return a column reference expression -#' @noRd -#' @examples -#' col_ref_expr <- expr_reference("some_column_name") -#' col_ref_expr2 <- expr_reference("some_column_name", "some_table_name") -expr_reference2 <- function(names, table = NULL, con = NULL) { - if (inherits(table, "data.frame")) { + } else if (inherits(table, "data.frame")) { names <- c(reldf_alias(table, con), names) - } - if (is.character(table) && !identical(table, "")) { + } else if (is.character(table) && !identical(table, "")) { names <- c(table, names) } + rethrow_rapi_expr_reference(names) } diff --git a/tests/testthat/test-rel_api2.R b/tests/testthat/test-rel_api2.R index 618abf871..17842e4d8 100644 --- a/tests/testthat/test-rel_api2.R +++ b/tests/testthat/test-rel_api2.R @@ -18,7 +18,7 @@ test_that("relational anti_join(join_by(a)) order-enforcing 2", { df4, con, list( - expr_function("___eq_na_matches_na", list(expr_reference2("a", df2, con), expr_reference2("a", df4, con))) + expr_function("___eq_na_matches_na", list(expr_reference("a", df2, con), expr_reference("a", df4, con))) ), "anti" ) @@ -52,7 +52,7 @@ test_that("relational anti_join(join_by(a)) order-enforcing 2", { df4, con, list( - expr_function("___eq_na_matches_na", list(expr_reference2("a", df2, con), expr_reference2("a", df4, con))) + expr_function("___eq_na_matches_na", list(expr_reference("a", df2, con), expr_reference("a", df4, con))) ), "anti" ) @@ -79,17 +79,17 @@ test_that("relational arrange(a) order-preserving 2", { con, list( { - tmp_expr <- expr_reference2("a") + tmp_expr <- expr_reference("a") expr_set_alias(tmp_expr, "a") tmp_expr }, { - tmp_expr <- expr_reference2("b") + tmp_expr <- expr_reference("b") expr_set_alias(tmp_expr, "b") tmp_expr }, { - tmp_expr <- expr_reference2("g") + tmp_expr <- expr_reference("g") expr_set_alias(tmp_expr, "g") tmp_expr }, @@ -101,7 +101,7 @@ test_that("relational arrange(a) order-preserving 2", { ) ) "arrange" - df3 <- reldf_order(df2, con, list(expr_reference2("a"), expr_reference2("___row_number"))) + df3 <- reldf_order(df2, con, list(expr_reference("a"), expr_reference("___row_number"))) "arrange" df4 <- reldf_project( df3, From c44eb94592f6565d2345c53ea688de6470c227a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Sat, 8 Mar 2025 17:48:27 +0100 Subject: [PATCH 57/69] Rethrow --- R/relational.R | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/R/relational.R b/R/relational.R index b005a6134..162a30a45 100644 --- a/R/relational.R +++ b/R/relational.R @@ -28,7 +28,9 @@ expr_reference <- function(names, table = NULL, con = NULL) { #' @examples #' const_int_expr <- expr_constant(42) #' const_str_expr <- expr_constant("Hello, World") -expr_constant <- rapi_expr_constant +expr_constant <- function(val) { + rethrow_rapi_expr_constant(val) +} #' Create a comparison expression #' @param exprs a vector of size two, the expressions to compare @@ -37,7 +39,9 @@ expr_constant <- rapi_expr_constant #' @noRd #' @examples #' comp_expr <- expr_comparison(">", list(expr_constant(-42), expr_constant(42))) -expr_comparison <- rapi_expr_comparison +expr_comparison <- function(cmp_op, exprs) { + rethrow_rapi_expr_comparison(cmp_op, exprs) +} #' Create a function call expression #' @param name the function name @@ -56,7 +60,9 @@ expr_function <- function(name, args, order_bys = list(), filter_bys = list()) { #' @noRd #' @examples #' expr_str <- expr_tostring(expr_constant(42)) -expr_tostring <- rapi_expr_tostring +expr_tostring <- function(expr) { + rethrow_rapi_expr_tostring(expr) +} #' Set the alias for an expression #' @param expr the expression @@ -64,7 +70,9 @@ expr_tostring <- rapi_expr_tostring #' @noRd #' @examples #' expr_set_alias(expr_constant(42), "my_alias") -expr_set_alias <- rapi_expr_set_alias +expr_set_alias <- function(expr, alias) { + rethrow_rapi_expr_set_alias(expr, alias) +} #' @export print.duckdb_expr <- function(x, ...) { @@ -269,6 +277,7 @@ reldf_order <- function(df, con, orders, ascending = NULL) { #' @noRd #' @examples #' null_ptr <- sexp_null_ptr() +# Not rethrowing, internal utility sexp_null_ptr <- rapi_get_null_SEXP_ptr expr_window <- function(window_function, partitions=list(), order_bys=list(), From e51d9aa746c1d80ddf9bb770ba3aab1b02d2af75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Sat, 8 Mar 2025 20:39:19 +0100 Subject: [PATCH 58/69] Move and tweak --- R/relational.R | 255 +-------------------------------------------- R/relational2.R | 269 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 270 insertions(+), 254 deletions(-) create mode 100644 R/relational2.R diff --git a/R/relational.R b/R/relational.R index 162a30a45..41edd172f 100644 --- a/R/relational.R +++ b/R/relational.R @@ -131,19 +131,6 @@ rel_limit <- function(rel, n) { rethrow_rapi_rel_limit(rel, n) } -#' Lazily retrieve the top-n rows of a DuckDB relation object -#' @param rel the DuckDB relation object -#' @param n the amount of rows to retrieve -#' @return the now limited `duckdb_relation` object -#' @noRd -#' @examples -#' con <- DBI::dbConnect(duckdb()) -#' rel <- rel_from_df(con, mtcars) -#' rel2 <- rel_limit(rel, 10) -reldf_limit <- function(df, con, n) { - rethrow_rapi_reldf_limit(df, con@conn_ref, n) -} - #' Lazily project a DuckDB relation object #' @param rel the DuckDB relation object #' @param exprs a list of DuckDB expressions to project @@ -157,19 +144,6 @@ rel_project <- function(rel, exprs) { rethrow_rapi_rel_project(rel, exprs) } -#' Lazily project a DuckDB relation object -#' @param rel the DuckDB relation object -#' @param exprs a list of DuckDB expressions to project -#' @return the now projected `duckdb_relation` object -#' @noRd -#' @examples -#' con <- DBI::dbConnect(duckdb()) -#' rel <- rel_from_df(con, mtcars) -#' rel2 <- rel_project(rel, list(expr_reference("cyl"), expr_reference("disp"))) -reldf_project <- function(df, con, exprs) { - rethrow_rapi_reldf_project(df, con@conn_ref, exprs) -} - #' Lazily filter a DuckDB relation object #' @param rel the DuckDB relation object #' @param exprs a list of DuckDB expressions to filter by @@ -184,20 +158,6 @@ rel_filter <- function(rel, exprs) { rethrow_rapi_rel_filter(rel, exprs) } -#' Lazily filter a DuckDB relation object -#' @param rel the DuckDB relation object -#' @param exprs a list of DuckDB expressions to filter by -#' @return the now filtered `duckdb_relation` object -#' @noRd -#' @examples -#' con <- DBI::dbConnect(duckdb()) -#' DBI::dbExecute(con, "CREATE OR REPLACE MACRO gt(a, b) AS a > b") -#' rel <- rel_from_df(con, mtcars) -#' rel2 <- rel_filter(rel, list(expr_function("gt", list(expr_reference("cyl"), expr_constant("6"))))) -reldf_filter <- function(df, con, exprs) { - rethrow_rapi_reldf_filter(df, con@conn_ref, exprs) -} - #' Lazily aggregate a DuckDB relation object #' @param rel the DuckDB relation object #' @param groups a list of DuckDB expressions to group by @@ -213,21 +173,6 @@ rel_aggregate <- function(rel, groups, aggregates) { rethrow_rapi_rel_aggregate(rel, groups, aggregates) } -#' Lazily aggregate a DuckDB relation object -#' @param rel the DuckDB relation object -#' @param groups a list of DuckDB expressions to group by -#' @param aggregates a (optionally named) list of DuckDB expressions with aggregates to compute -#' @return the now aggregated `duckdb_relation` object -#' @noRd -#' @examples -#' con <- DBI::dbConnect(duckdb()) -#' rel <- rel_from_df(con, mtcars) -#' aggrs <- list(avg_hp = expr_function("avg", list(expr_reference("hp")))) -#' rel2 <- rel_aggregate(rel, list(expr_reference("cyl")), aggrs) -reldf_aggregate <- function(df, con, groups, aggregates) { - rethrow_rapi_reldf_aggregate(df, con@conn_ref, groups, aggregates) -} - #' Lazily reorder a DuckDB relation object #' @param rel the DuckDB relation object #' @param orders a list of DuckDB expressions to order by @@ -250,28 +195,6 @@ rel_order <- function(rel, orders, ascending = NULL) { return(rethrow_rapi_rel_order(rel, orders, ascending)) } -#' Lazily reorder a DuckDB relation object -#' @param rel the DuckDB relation object -#' @param orders a list of DuckDB expressions to order by -#' @param ascending a vector of boolean values describing sort order of expressions. True for ascending. -#' @return the now aggregated `duckdb_relation` object -#' @noRd -#' @examples -#' con <- DBI::dbConnect(duckdb()) -#' rel <- rel_from_df(con, mtcars) -#' rel2 <- rel_order(rel, list(expr_reference("hp"))) -reldf_order <- function(df, con, orders, ascending = NULL) { - if (is.null(ascending)) { - ascending <- rep(TRUE, length(orders)) - } - - if (length(orders) != length(ascending)) { - stop("length of ascending must equal length of orders") - } - - return(rethrow_rapi_reldf_order(df, con@conn_ref, orders, ascending)) -} - #' Get an external pointer pointing to NULL #' @return an external pointer pointing to null_ptr. #' @noRd @@ -350,24 +273,6 @@ rel_join <- function(left, right, conds, rethrow_rapi_rel_join(left, right, conds, join, join_ref_type) } -reldf_join <- function( - left, - right, - con, - conds, - join = c("inner", "left", "right", "outer", "cross", "semi", "anti"), - join_ref_type = c("regular", "natural", "cross", "positional", "asof") -) { - join <- match.arg(join) - join_ref_type <- match.arg(join_ref_type) - # the ref type is naturally regular. Users won't write rel_join(left, right, conds, "cross", "cross") - # so we update it here. - if (join == "cross" && join_ref_type == "regular") { - join_ref_type <- "cross" - } - rethrow_rapi_reldf_join(left, right, con@conn_ref, conds, join, join_ref_type) -} - #' UNION ALL on two DuckDB relation objects #' @param rel_a a DuckDB relation object #' @param rel_b a DuckDB relation object @@ -382,20 +287,6 @@ rel_union_all <- function(rel_a, rel_b) { rethrow_rapi_rel_union_all(rel_a, rel_b) } -#' UNION ALL on two DuckDB relation objects -#' @param rel_a a DuckDB relation object -#' @param rel_b a DuckDB relation object -#' @return a new `duckdb_relation` object resulting from the union -#' @noRd -#' @examples -#' con <- DBI::dbConnect(duckdb()) -#' rel_a <- rel_from_df(con, mtcars) -#' rel_b <- rel_from_df(con, mtcars) -#' rel_union_all(rel_a, rel_b) -reldf_union_all <- function(df_a, df_b, con) { - rethrow_rapi_reldf_union_all(df_a, df_b, con@conn_ref) -} - #' Lazily compute a distinct result on a DuckDB relation object #' @param rel the input DuckDB relation object #' @return a new `duckdb_relation` object with distinct rows @@ -408,18 +299,6 @@ rel_distinct <- function(rel) { rethrow_rapi_rel_distinct(rel) } -#' Lazily compute a distinct result on a DuckDB relation object -#' @param rel the input DuckDB relation object -#' @return a new `duckdb_relation` object with distinct rows -#' @noRd -#' @examples -#' con <- DBI::dbConnect(duckdb()) -#' rel <- rel_from_df(con, mtcars) -#' rel2 <- rel_distinct(rel) -reldf_distinct <- function(df, con) { - rethrow_rapi_reldf_distinct(df, con@conn_ref) -} - #' SET INTERSECT on two DuckDB relation objects #' @param rel_a a DuckDB relation object #' @param rel_b a DuckDB relation object @@ -433,19 +312,6 @@ rel_set_intersect <- function(rel_a, rel_b) { rethrow_rapi_rel_set_intersect(rel_a, rel_b) } -#' SET INTERSECT on two DuckDB relation objects -#' @param rel_a a DuckDB relation object -#' @param rel_b a DuckDB relation object -#' @return a new `duckdb_relation` object resulting from the intersection -#' @noRd -#' @examples -#' rel_a <- rel_from_df(con, mtcars) -#' rel_b <- rel_from_df(con, mtcars) -#' rel_set_intersect_all(rel_a, rel_b) -reldf_set_intersect <- function(df_a, df_b, con) { - rethrow_rapi_reldf_set_intersect(df_a, df_b, con@conn_ref) -} - #' SET DIFF on two DuckDB relation objects #' @param rel_a a DuckDB relation object #' @param rel_b a DuckDB relation object @@ -459,19 +325,6 @@ rel_set_diff <- function(rel_a, rel_b) { rethrow_rapi_rel_set_diff(rel_a, rel_b) } -#' SET DIFF on two DuckDB relation objects -#' @param rel_a a DuckDB relation object -#' @param rel_b a DuckDB relation object -#' @return a new `duckdb_relation` object resulting from the set difference -#' @noRd -#' @examples -#' rel_a <- rel_from_df(con, mtcars) -#' rel_b <- rel_from_df(con, mtcars) -#' rel_set_diff(rel_a, rel_b) -reldf_set_diff <- function(df_a, df_b, con) { - rethrow_rapi_reldf_set_diff(df_a, df_b, con@conn_ref) -} - #' SET SYMDIFF on two DuckDB relation objects #' @param rel_a a DuckDB relation object #' @param rel_b a DuckDB relation object @@ -485,19 +338,6 @@ rel_set_symdiff <- function(rel_a, rel_b) { rethrow_rapi_rel_set_symdiff(rel_a, rel_b) } -#' SET SYMDIFF on two DuckDB relation objects -#' @param rel_a a DuckDB relation object -#' @param rel_b a DuckDB relation object -#' @return a new `duckdb_relation` object resulting from the symmetric difference of rel_a and rel_b -#' @noRd -#' @examples -#' rel_a <- rel_from_df(con, mtcars) -#' rel_b <- rel_from_df(con, mtcars) -#' rel_set_symdiff(rel_a, rel_b) -reldf_set_symdiff <- function(df_a, df_b, con) { - rethrow_rapi_reldf_set_symdiff(df_a, df_b, con@conn_ref) -} - #' Run a SQL query on a DuckDB relation object #' @param rel the DuckDB relation object #' @param sql a SQL query to run, use `_` to refer back to the relation @@ -520,20 +360,7 @@ rel_sql <- function(rel, sql) { #' rel_explain(rel) rel_explain <- function(rel) { # Legacy - cat(rethrow_rapi_reldf_explain(rel, "EXPLAIN_STANDARD", "DEFAULT")[[]][[1]]) - invisible(NULL) -} - -#' Print the EXPLAIN output for a DuckDB relation object -#' @param rel the DuckDB relation object -#' @noRd -#' @examples -#' con <- DBI::dbConnect(duckdb()) -#' rel <- rel_from_df(con, mtcars) -#' rel_explain(rel) -reldf_explain <- function(df, con) { - # Legacy - cat(rethrow_rapi_reldf_explain(df, con@conn_ref, "EXPLAIN_STANDARD", "DEFAULT")[[2]][[1]]) + cat(rethrow_rapi_rel_explain(rel, "EXPLAIN_STANDARD", "DEFAULT")[[2]][[1]]) invisible(NULL) } @@ -577,17 +404,6 @@ rel_alias <- function(rel) { rethrow_rapi_rel_alias(rel) } -#' Get the internal alias for a DuckDB relation object -#' @param rel the DuckDB relation object -#' @noRd -#' @examples -#' con <- DBI::dbConnect(duckdb()) -#' rel <- rel_from_df(con, mtcars) -#' rel_alias(rel) -reldf_alias <- function(df, con) { - rethrow_rapi_reldf_alias(df, con@conn_ref) -} - #' Set the internal alias for a DuckDB relation object #' @param rel the DuckDB relation object #' @param alias the new alias @@ -600,18 +416,6 @@ rel_set_alias <- function(rel, alias) { rethrow_rapi_rel_set_alias(rel, alias) } -#' Set the internal alias for a DuckDB relation object -#' @param rel the DuckDB relation object -#' @param alias the new alias -#' @noRd -#' @examples -#' con <- DBI::dbConnect(duckdb()) -#' rel <- rel_from_df(con, mtcars) -#' rel_set_alias(rel, "my_new_alias") -reldf_set_alias <- function(df, con, alias) { - rethrow_rapi_reldf_set_alias(df, con@conn_ref, alias) -} - #' Transforms a relation object to a lazy data frame using altrep #' @param rel the DuckDB relation object #' @return a data frame @@ -678,18 +482,6 @@ rel_from_sql <- function(con, sql) { rethrow_rapi_rel_from_sql(con@conn_ref, sql) } -#' Create a duckdb table relation from a table name -#' @param sql An SQL query -#' @return a duckdb relation -#' @noRd -#' @examples -#' con <- DBI::dbConnect(duckdb()) -#' DBI::dbWriteTable(con, "mtcars", mtcars) -#' rel <- rel_from_sql(con, "SELECT * FROM mtcars") -reldf_from_sql <- function(con, sql) { - rethrow_rapi_reldf_from_sql(con@conn_ref, sql) -} - #' Create a duckdb table relation from a table name #' @param table the table name #' @return a duckdb relation @@ -702,18 +494,6 @@ rel_from_table <- function(con, table_name, schema_name = "MAIN") { rethrow_rapi_rel_from_table(con@conn_ref, schema_name, table_name) } -#' Create a duckdb table relation from a table name -#' @param table the table name -#' @return a duckdb relation -#' @noRd -#' @examples -#' con <- DBI::dbConnect(duckdb()) -#' DBI::dbWriteTable(con, "mtcars", mtcars) -#' rel <- rel_from_table(con, "mtcars") -reldf_from_table <- function(con, table_name, schema_name = "MAIN") { - rethrow_rapi_reldf_from_table(con@conn_ref, schema_name, table_name) -} - #' Convert a duckdb relation from a table-producing function #' @param name the table function name #' @param positional_parameters the table function positional parameters list @@ -727,59 +507,26 @@ rel_from_table_function <- function(con, function_name, positional_parameters = rethrow_rapi_rel_from_table_function(con@conn_ref, function_name, positional_parameters, named_parameters) } -#' Convert a duckdb relation from a table-producing function -#' @param name the table function name -#' @param positional_parameters the table function positional parameters list -#' @param named_parameters the table function named parameters list -#' @return a duckdb relation -#' @noRd -#' @examples -#' con <- DBI::dbConnect(duckdb()) -#' rel <- rel_from_table_function(con, 'generate_series', list(10L)) -reldf_from_table_function <- function(con, function_name, positional_parameters = list(), named_parameters = list()) { - rethrow_rapi_reldf_from_table_function(con@conn_ref, function_name, positional_parameters, named_parameters) -} - rel_to_parquet <- function(rel, file_name, options = list()) { rethrow_rapi_rel_to_parquet(rel, file_name, options) } -reldf_to_parquet <- function(df, con, file_name, options = list()) { - rethrow_rapi_reldf_to_parquet(df, con@conn_ref, file_name, options) -} - rel_to_csv <- function(rel, file_name, options = list()) { rethrow_rapi_rel_to_csv(rel, file_name, options) } -reldf_to_csv <- function(df, con, file_name, options = list()) { - rethrow_rapi_reldf_to_csv(df, con@conn_ref, file_name, options) -} - rel_to_table <- function(rel, schema_name, table_name, temporary) { rethrow_rapi_rel_to_table(rel, schema_name, table_name, temporary) } -reldf_to_table <- function(df, con, schema_name, table_name, temporary) { - rethrow_rapi_reldf_to_table(df, con@conn_ref, schema_name, table_name, temporary) -} - rel_insert <- function(rel, schema_name, table_name) { rethrow_rapi_rel_insert(rel, schema_name, table_name) } -reldf_insert <- function(df, con, schema_name, table_name) { - rethrow_rapi_reldf_insert(df, con@conn_ref, schema_name, table_name) -} - rel_names <- function(rel) { rethrow_rapi_rel_names(rel) } -reldf_names <- function(df, con) { - rethrow_rapi_reldf_names(df, con@conn_ref) -} - load_rfuns <- function() { rethrow_rapi_load_rfuns() } diff --git a/R/relational2.R b/R/relational2.R new file mode 100644 index 000000000..a4cd14f76 --- /dev/null +++ b/R/relational2.R @@ -0,0 +1,269 @@ +#' Lazily retrieve the top-n rows of a DuckDB relation object +#' @param rel the DuckDB relation object +#' @param n the amount of rows to retrieve +#' @return the now limited `duckdb_relation` object +#' @noRd +#' @examples +#' con <- DBI::dbConnect(duckdb()) +#' rel <- rel_from_df(con, mtcars) +#' rel2 <- rel_limit(rel, 10) +reldf_limit <- function(df, con, n) { + rethrow_rapi_reldf_limit(df, con@conn_ref, n) +} + +#' Lazily project a DuckDB relation object +#' @param rel the DuckDB relation object +#' @param exprs a list of DuckDB expressions to project +#' @return the now projected `duckdb_relation` object +#' @noRd +#' @examples +#' con <- DBI::dbConnect(duckdb()) +#' rel <- rel_from_df(con, mtcars) +#' rel2 <- rel_project(rel, list(expr_reference("cyl"), expr_reference("disp"))) +reldf_project <- function(df, con, exprs) { + rethrow_rapi_reldf_project(df, con@conn_ref, exprs) +} + +#' Lazily filter a DuckDB relation object +#' @param rel the DuckDB relation object +#' @param exprs a list of DuckDB expressions to filter by +#' @return the now filtered `duckdb_relation` object +#' @noRd +#' @examples +#' con <- DBI::dbConnect(duckdb()) +#' DBI::dbExecute(con, "CREATE OR REPLACE MACRO gt(a, b) AS a > b") +#' rel <- rel_from_df(con, mtcars) +#' rel2 <- rel_filter(rel, list(expr_function("gt", list(expr_reference("cyl"), expr_constant("6"))))) +reldf_filter <- function(df, con, exprs) { + rethrow_rapi_reldf_filter(df, con@conn_ref, exprs) +} + +#' Lazily aggregate a DuckDB relation object +#' @param rel the DuckDB relation object +#' @param groups a list of DuckDB expressions to group by +#' @param aggregates a (optionally named) list of DuckDB expressions with aggregates to compute +#' @return the now aggregated `duckdb_relation` object +#' @noRd +#' @examples +#' con <- DBI::dbConnect(duckdb()) +#' rel <- rel_from_df(con, mtcars) +#' aggrs <- list(avg_hp = expr_function("avg", list(expr_reference("hp")))) +#' rel2 <- rel_aggregate(rel, list(expr_reference("cyl")), aggrs) +reldf_aggregate <- function(df, con, groups, aggregates) { + rethrow_rapi_reldf_aggregate(df, con@conn_ref, groups, aggregates) +} + +#' Lazily reorder a DuckDB relation object +#' @param rel the DuckDB relation object +#' @param orders a list of DuckDB expressions to order by +#' @param ascending a vector of boolean values describing sort order of expressions. True for ascending. +#' @return the now aggregated `duckdb_relation` object +#' @noRd +#' @examples +#' con <- DBI::dbConnect(duckdb()) +#' rel <- rel_from_df(con, mtcars) +#' rel2 <- rel_order(rel, list(expr_reference("hp"))) +reldf_order <- function(df, con, orders, ascending = NULL) { + if (is.null(ascending)) { + ascending <- rep(TRUE, length(orders)) + } + + if (length(orders) != length(ascending)) { + stop("length of ascending must equal length of orders") + } + + return(rethrow_rapi_reldf_order(df, con@conn_ref, orders, ascending)) +} + +#' Lazily INNER join two DuckDB relation objects +#' @param left the left-hand-side DuckDB relation object +#' @param right the right-hand-side DuckDB relation object +#' @param conds a list of DuckDB expressions to use for the join +#' @param join a string describing the join type (either "inner", "left", "right", or "outer") +#' @return a new `duckdb_relation` object resulting from the join +#' @noRd +#' @examples +#' con <- DBI::dbConnect(duckdb()) +#' DBI::dbExecute(con, "CREATE OR REPLACE MACRO eq(a, b) AS a = b") +#' left <- rel_from_df(con, mtcars) +#' right <- rel_from_df(con, mtcars) +#' cond <- list(expr_function("eq", list(expr_reference("cyl", left), expr_reference("cyl", right)))) +#' rel2 <- rel_join(left, right, cond, "inner") +#' rel2 <- rel_join(left, right, cond, "right") +#' rel2 <- rel_join(left, right, cond, "left") +#' rel2 <- rel_join(left, right, cond, "outer") +reldf_join <- function( + left, + right, + con, + conds, + join = c("inner", "left", "right", "outer", "cross", "semi", "anti"), + join_ref_type = c("regular", "natural", "cross", "positional", "asof") +) { + join <- match.arg(join) + join_ref_type <- match.arg(join_ref_type) + # the ref type is naturally regular. Users won't write rel_join(left, right, conds, "cross", "cross") + # so we update it here. + if (join == "cross" && join_ref_type == "regular") { + join_ref_type <- "cross" + } + rethrow_rapi_reldf_join(left, right, con@conn_ref, conds, join, join_ref_type) +} + +#' UNION ALL on two DuckDB relation objects +#' @param rel_a a DuckDB relation object +#' @param rel_b a DuckDB relation object +#' @return a new `duckdb_relation` object resulting from the union +#' @noRd +#' @examples +#' con <- DBI::dbConnect(duckdb()) +#' rel_a <- rel_from_df(con, mtcars) +#' rel_b <- rel_from_df(con, mtcars) +#' rel_union_all(rel_a, rel_b) +reldf_union_all <- function(df_a, df_b, con) { + rethrow_rapi_reldf_union_all(df_a, df_b, con@conn_ref) +} + +#' Lazily compute a distinct result on a DuckDB relation object +#' @param rel the input DuckDB relation object +#' @return a new `duckdb_relation` object with distinct rows +#' @noRd +#' @examples +#' con <- DBI::dbConnect(duckdb()) +#' rel <- rel_from_df(con, mtcars) +#' rel2 <- rel_distinct(rel) +reldf_distinct <- function(df, con) { + rethrow_rapi_reldf_distinct(df, con@conn_ref) +} + +#' SET INTERSECT on two DuckDB relation objects +#' @param rel_a a DuckDB relation object +#' @param rel_b a DuckDB relation object +#' @return a new `duckdb_relation` object resulting from the intersection +#' @noRd +#' @examples +#' rel_a <- rel_from_df(con, mtcars) +#' rel_b <- rel_from_df(con, mtcars) +#' rel_set_intersect_all(rel_a, rel_b) +reldf_set_intersect <- function(df_a, df_b, con) { + rethrow_rapi_reldf_set_intersect(df_a, df_b, con@conn_ref) +} + +#' SET DIFF on two DuckDB relation objects +#' @param rel_a a DuckDB relation object +#' @param rel_b a DuckDB relation object +#' @return a new `duckdb_relation` object resulting from the set difference +#' @noRd +#' @examples +#' rel_a <- rel_from_df(con, mtcars) +#' rel_b <- rel_from_df(con, mtcars) +#' rel_set_diff(rel_a, rel_b) +reldf_set_diff <- function(df_a, df_b, con) { + rethrow_rapi_reldf_set_diff(df_a, df_b, con@conn_ref) +} + +#' SET SYMDIFF on two DuckDB relation objects +#' @param rel_a a DuckDB relation object +#' @param rel_b a DuckDB relation object +#' @return a new `duckdb_relation` object resulting from the symmetric difference of rel_a and rel_b +#' @noRd +#' @examples +#' rel_a <- rel_from_df(con, mtcars) +#' rel_b <- rel_from_df(con, mtcars) +#' rel_set_symdiff(rel_a, rel_b) +reldf_set_symdiff <- function(df_a, df_b, con) { + rethrow_rapi_reldf_set_symdiff(df_a, df_b, con@conn_ref) +} + +#' Print the EXPLAIN output for a DuckDB relation object +#' @param rel the DuckDB relation object +#' @noRd +#' @examples +#' con <- DBI::dbConnect(duckdb()) +#' rel <- rel_from_df(con, mtcars) +#' rel_explain(rel) +reldf_explain <- function(df, con) { + # Legacy + cat(rethrow_rapi_reldf_explain(df, con@conn_ref, "EXPLAIN_STANDARD", "DEFAULT")[[2]][[1]]) + invisible(NULL) +} + +#' Get the internal alias for a DuckDB relation object +#' @param rel the DuckDB relation object +#' @noRd +#' @examples +#' con <- DBI::dbConnect(duckdb()) +#' rel <- rel_from_df(con, mtcars) +#' rel_alias(rel) +reldf_alias <- function(df, con) { + rethrow_rapi_reldf_alias(df, con@conn_ref) +} + +#' Set the internal alias for a DuckDB relation object +#' @param rel the DuckDB relation object +#' @param alias the new alias +#' @noRd +#' @examples +#' con <- DBI::dbConnect(duckdb()) +#' rel <- rel_from_df(con, mtcars) +#' rel_set_alias(rel, "my_new_alias") +reldf_set_alias <- function(df, con, alias) { + rethrow_rapi_reldf_set_alias(df, con@conn_ref, alias) +} + +#' Create a duckdb table relation from a table name +#' @param sql An SQL query +#' @return a duckdb relation +#' @noRd +#' @examples +#' con <- DBI::dbConnect(duckdb()) +#' DBI::dbWriteTable(con, "mtcars", mtcars) +#' rel <- rel_from_sql(con, "SELECT * FROM mtcars") +reldf_from_sql <- function(con, sql) { + rethrow_rapi_reldf_from_sql(con@conn_ref, sql) +} + +#' Create a duckdb table relation from a table name +#' @param table the table name +#' @return a duckdb relation +#' @noRd +#' @examples +#' con <- DBI::dbConnect(duckdb()) +#' DBI::dbWriteTable(con, "mtcars", mtcars) +#' rel <- rel_from_table(con, "mtcars") +reldf_from_table <- function(con, table_name, schema_name = "MAIN") { + rethrow_rapi_reldf_from_table(con@conn_ref, schema_name, table_name) +} + +#' Convert a duckdb relation from a table-producing function +#' @param name the table function name +#' @param positional_parameters the table function positional parameters list +#' @param named_parameters the table function named parameters list +#' @return a duckdb relation +#' @noRd +#' @examples +#' con <- DBI::dbConnect(duckdb()) +#' rel <- rel_from_table_function(con, 'generate_series', list(10L)) +reldf_from_table_function <- function(con, function_name, positional_parameters = list(), named_parameters = list()) { + rethrow_rapi_reldf_from_table_function(con@conn_ref, function_name, positional_parameters, named_parameters) +} + +reldf_to_parquet <- function(df, con, file_name, options = list()) { + rethrow_rapi_reldf_to_parquet(df, con@conn_ref, file_name, options) +} + +reldf_to_csv <- function(df, con, file_name, options = list()) { + rethrow_rapi_reldf_to_csv(df, con@conn_ref, file_name, options) +} + +reldf_to_table <- function(df, con, schema_name, table_name, temporary) { + rethrow_rapi_reldf_to_table(df, con@conn_ref, schema_name, table_name, temporary) +} + +reldf_insert <- function(df, con, schema_name, table_name) { + rethrow_rapi_reldf_insert(df, con@conn_ref, schema_name, table_name) +} + +reldf_names <- function(df, con) { + rethrow_rapi_reldf_names(df, con@conn_ref) +} From a55d2bdb0c9c5c8422a95d4e1ebf3250e864059d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Sat, 8 Mar 2025 20:39:56 +0100 Subject: [PATCH 59/69] Revert bogus changes --- tests/testthat/_snaps/relational.md | 12 +- tests/testthat/test-list.R | 2 +- tests/testthat/test-parquet.R | 6 +- tests/testthat/test-readonly.R | 2 +- tests/testthat/test-rel_api.R | 228 ++++++++++++++-------------- tests/testthat/test-relational.R | 196 ++++++++++++------------ 6 files changed, 223 insertions(+), 223 deletions(-) diff --git a/tests/testthat/_snaps/relational.md b/tests/testthat/_snaps/relational.md index 102990f90..dcbd2ed97 100644 --- a/tests/testthat/_snaps/relational.md +++ b/tests/testthat/_snaps/relational.md @@ -113,7 +113,7 @@ # rel_explain() Code - writeLines(reldf_explain_df(proj)[[]]) + writeLines(rel_explain_df(proj)[[2]]) Output ┌───────────────────────────┐ │ R_DATAFRAME_SCAN │ @@ -128,14 +128,14 @@ --- Code - writeLines(reldf_explain_df(proj, "analyze")[[]]) + writeLines(rel_explain_df(proj, "analyze")[[2]]) Output Query profiling is disabled. Use 'PRAGMA enable_profiling;' to enable profiling! --- Code - writeLines(reldf_explain_df(proj, "standard", "json")[[]]) + writeLines(rel_explain_df(proj, "standard", "json")[[2]]) Output [ { @@ -152,7 +152,7 @@ --- Code - writeLines(reldf_explain_df(proj, "analyze", "json")[[]]) + writeLines(rel_explain_df(proj, "analyze", "json")[[2]]) Output { "result": "disabled" @@ -161,7 +161,7 @@ --- Code - writeLines(reldf_explain_df(proj, "standard", "html")[[]]) + writeLines(rel_explain_df(proj, "standard", "html")[[2]]) Output @@ -302,7 +302,7 @@ --- Code - writeLines(reldf_explain_df(proj, "standard", "graphviz")[[]]) + writeLines(rel_explain_df(proj, "standard", "graphviz")[[2]]) Output digraph G { diff --git a/tests/testthat/test-list.R b/tests/testthat/test-list.R index a2d020194..5c3873ef6 100644 --- a/tests/testthat/test-list.R +++ b/tests/testthat/test-list.R @@ -39,6 +39,6 @@ test_that("rel_filter() handles LIST logical type", { rel1 <- rel_from_df(con, df1) rel2 <- rel_filter(rel1, list(expr_constant(TRUE))) - df2 <- reldf_to_altrep(rel) + df2 <- rel_to_altrep(rel2) expect_equal(df1$a, df2$a) }) diff --git a/tests/testthat/test-parquet.R b/tests/testthat/test-parquet.R index c6fa7f32f..e7b54656b 100644 --- a/tests/testthat/test-parquet.R +++ b/tests/testthat/test-parquet.R @@ -60,10 +60,10 @@ test_that("duckdb rel_to_parquet() allows multiple files (#1015)", { rel_to_parquet(rel1, tf1) tf2 <- tempfile(fileext = ".parquet") - rel2 <- reldf_from_df(con, data.frame(a = )) - reldf_to_parquet(rel, tf2) + rel2 <- rel_from_df(con, data.frame(a = 2)) + rel_to_parquet(rel2, tf2) - res_rel <- reldf_from_table_function(con, "read_parquet", list(list(c(tf1, tf)))) + res_rel <- rel_from_table_function(con, "read_parquet", list(list(c(tf1, tf2)))) res_df <- rel_to_altrep(res_rel) expect_identical(res_df, data.frame(a = c(1, 2))) diff --git a/tests/testthat/test-readonly.R b/tests/testthat/test-readonly.R index 674812ca3..ce536c234 100644 --- a/tests/testthat/test-readonly.R +++ b/tests/testthat/test-readonly.R @@ -76,6 +76,6 @@ test_that("read_only flag still throws error when table is attempted to be creat con <- dbConnect(duckdb(), db_path, read_only=TRUE) rel <- duckdb:::rel_from_df(con, mtcars) - expect_error(duckdb:::reldf_sql(rel, "create table t as (SELECT cyl, disp FROM _ )")) + expect_error(duckdb:::rel_sql(rel, "create table t2 as (SELECT cyl, disp FROM _ )")) dbDisconnect(con) }) diff --git a/tests/testthat/test-rel_api.R b/tests/testthat/test-rel_api.R index c61d7c67a..357a09885 100644 --- a/tests/testthat/test-rel_api.R +++ b/tests/testthat/test-rel_api.R @@ -19,7 +19,7 @@ test_that("relational anti_join(join_by(a)) order-preserving", { df2 <- data.frame(a = 2:5, b = 2) "anti_join" - rel3 <- reldf_from_df(con, df, experimental = experimental) + rel3 <- rel_from_df(con, df2, experimental = experimental) "anti_join" rel4 <- rel_set_alias(rel3, "rhs") "anti_join" @@ -98,7 +98,7 @@ test_that("relational anti_join(join_by(a)) order-enforcing", { df2 <- data.frame(a = 2:5, b = 2) "anti_join" - rel3 <- reldf_from_df(con, df, experimental = experimental) + rel3 <- rel_from_df(con, df2, experimental = experimental) "anti_join" rel4 <- rel_set_alias(rel3, "rhs") "anti_join" @@ -177,7 +177,7 @@ test_that("relational arrange(a) order-preserving", { ) ) "arrange" - rel3 <- reldf_order(rel, list(expr_reference("a"), expr_reference("___row_number"))) + rel3 <- rel_order(rel2, list(expr_reference("a"), expr_reference("___row_number"))) "arrange" rel4 <- rel_project( rel3, @@ -244,7 +244,7 @@ test_that("relational arrange(g) order-preserving", { ) ) "arrange" - rel3 <- reldf_order(rel, list(expr_reference("g"), expr_reference("___row_number"))) + rel3 <- rel_order(rel2, list(expr_reference("g"), expr_reference("___row_number"))) "arrange" rel4 <- rel_project( rel3, @@ -567,7 +567,7 @@ test_that("relational count() order-preserving", { ) ) rel2 - out <- reldf_to_altrep(rel) + out <- rel_to_altrep(rel2) expect_identical( out, data.frame(n = 6L) @@ -860,7 +860,7 @@ test_that("relational count() order-enforcing", { ) ) "arrange" - rel3 <- reldf_order(rel, list(expr_reference("n"))) + rel3 <- rel_order(rel2, list(expr_reference("n"))) rel3 out <- rel_to_altrep(rel3) expect_identical( @@ -1720,7 +1720,7 @@ test_that("relational union_all(data.frame(a = 1L, b = 3, g = 2L)) %>% distinct( df2 <- data.frame(a = 1L, b = 3, g = 2L) "union_all" - rel2 <- reldf_from_df(con, df, experimental = experimental) + rel2 <- rel_from_df(con, df2, experimental = experimental) "union_all" rel3 <- rel_project( rel1, @@ -1905,7 +1905,7 @@ test_that("relational union_all(data.frame(a = 1L, b = 3, g = 2L)) %>% distinct( ) ) rel12 - out <- reldf_to_altrep(rel1) + out <- rel_to_altrep(rel12) expect_identical( out, data.frame(g = 1:3) @@ -1925,7 +1925,7 @@ test_that("relational union_all(data.frame(a = 1L, b = 4, g = 2L)) %>% distinct( df2 <- data.frame(a = 1L, b = 4, g = 2L) "union_all" - rel2 <- reldf_from_df(con, df, experimental = experimental) + rel2 <- rel_from_df(con, df2, experimental = experimental) "union_all" rel3 <- rel_project( rel1, @@ -2110,7 +2110,7 @@ test_that("relational union_all(data.frame(a = 1L, b = 4, g = 2L)) %>% distinct( ) ) rel12 - out <- reldf_to_altrep(rel1) + out <- rel_to_altrep(rel12) expect_identical( out, data.frame(g = 1:3) @@ -2130,7 +2130,7 @@ test_that("relational union_all(data.frame(a = 1L, b = 5, g = 2L)) %>% distinct( df2 <- data.frame(a = 1L, b = 5, g = 2L) "union_all" - rel2 <- reldf_from_df(con, df, experimental = experimental) + rel2 <- rel_from_df(con, df2, experimental = experimental) "union_all" rel3 <- rel_project( rel1, @@ -2315,7 +2315,7 @@ test_that("relational union_all(data.frame(a = 1L, b = 5, g = 2L)) %>% distinct( ) ) rel12 - out <- reldf_to_altrep(rel1) + out <- rel_to_altrep(rel12) expect_identical( out, data.frame(g = 1:3) @@ -2335,7 +2335,7 @@ test_that("relational union_all(data.frame(a = 1L, b = 6, g = 2L)) %>% distinct( df2 <- data.frame(a = 1L, b = 6, g = 2L) "union_all" - rel2 <- reldf_from_df(con, df, experimental = experimental) + rel2 <- rel_from_df(con, df2, experimental = experimental) "union_all" rel3 <- rel_project( rel1, @@ -2520,7 +2520,7 @@ test_that("relational union_all(data.frame(a = 1L, b = 6, g = 2L)) %>% distinct( ) ) rel12 - out <- reldf_to_altrep(rel1) + out <- rel_to_altrep(rel12) expect_identical( out, data.frame(g = 1:3) @@ -2540,7 +2540,7 @@ test_that("relational union_all(data.frame(a = 1L, b = 7, g = 2L)) %>% distinct( df2 <- data.frame(a = 1L, b = 7, g = 2L) "union_all" - rel2 <- reldf_from_df(con, df, experimental = experimental) + rel2 <- rel_from_df(con, df2, experimental = experimental) "union_all" rel3 <- rel_project( rel1, @@ -2725,7 +2725,7 @@ test_that("relational union_all(data.frame(a = 1L, b = 7, g = 2L)) %>% distinct( ) ) rel12 - out <- reldf_to_altrep(rel1) + out <- rel_to_altrep(rel12) expect_identical( out, data.frame(g = 1:3) @@ -2904,7 +2904,7 @@ test_that("relational distinct(a) order-enforcing", { ) ) "distinct" - rel3 <- reldf_distinct(rel) + rel3 <- rel_distinct(rel2) "arrange" rel4 <- rel_order(rel3, list(expr_reference("a"))) rel4 @@ -2942,7 +2942,7 @@ test_that("relational distinct(a, b) order-enforcing", { ) ) "distinct" - rel3 <- reldf_distinct(rel) + rel3 <- rel_distinct(rel2) "arrange" rel4 <- rel_order(rel3, list(expr_reference("a"), expr_reference("b"))) rel4 @@ -2975,7 +2975,7 @@ test_that("relational distinct(b, b) order-enforcing", { ) ) "distinct" - rel3 <- reldf_distinct(rel) + rel3 <- rel_distinct(rel2) "arrange" rel4 <- rel_order(rel3, list(expr_reference("b"))) rel4 @@ -3008,7 +3008,7 @@ test_that("relational distinct(g) order-enforcing", { ) ) "distinct" - rel3 <- reldf_distinct(rel) + rel3 <- rel_distinct(rel2) "arrange" rel4 <- rel_order(rel3, list(expr_reference("g"))) rel4 @@ -3032,9 +3032,9 @@ test_that("relational union_all(data.frame(a = 1L, b = 3, g = 2L)) %>% distinct( df2 <- data.frame(a = 1L, b = 3, g = 2L) "union_all" - rel2 <- reldf_from_df(con, df, experimental = experimental) + rel2 <- rel_from_df(con, df2, experimental = experimental) "union_all" - rel3 <- reldf_union_all(rel1, rel) + rel3 <- rel_union_all(rel1, rel2) "distinct" rel4 <- rel_project( rel3, @@ -3071,9 +3071,9 @@ test_that("relational union_all(data.frame(a = 1L, b = 4, g = 2L)) %>% distinct( df2 <- data.frame(a = 1L, b = 4, g = 2L) "union_all" - rel2 <- reldf_from_df(con, df, experimental = experimental) + rel2 <- rel_from_df(con, df2, experimental = experimental) "union_all" - rel3 <- reldf_union_all(rel1, rel) + rel3 <- rel_union_all(rel1, rel2) "distinct" rel4 <- rel_project( rel3, @@ -3110,9 +3110,9 @@ test_that("relational union_all(data.frame(a = 1L, b = 5, g = 2L)) %>% distinct( df2 <- data.frame(a = 1L, b = 5, g = 2L) "union_all" - rel2 <- reldf_from_df(con, df, experimental = experimental) + rel2 <- rel_from_df(con, df2, experimental = experimental) "union_all" - rel3 <- reldf_union_all(rel1, rel) + rel3 <- rel_union_all(rel1, rel2) "distinct" rel4 <- rel_project( rel3, @@ -3149,9 +3149,9 @@ test_that("relational union_all(data.frame(a = 1L, b = 6, g = 2L)) %>% distinct( df2 <- data.frame(a = 1L, b = 6, g = 2L) "union_all" - rel2 <- reldf_from_df(con, df, experimental = experimental) + rel2 <- rel_from_df(con, df2, experimental = experimental) "union_all" - rel3 <- reldf_union_all(rel1, rel) + rel3 <- rel_union_all(rel1, rel2) "distinct" rel4 <- rel_project( rel3, @@ -3188,9 +3188,9 @@ test_that("relational union_all(data.frame(a = 1L, b = 7, g = 2L)) %>% distinct( df2 <- data.frame(a = 1L, b = 7, g = 2L) "union_all" - rel2 <- reldf_from_df(con, df, experimental = experimental) + rel2 <- rel_from_df(con, df2, experimental = experimental) "union_all" - rel3 <- reldf_union_all(rel1, rel) + rel3 <- rel_union_all(rel1, rel2) "distinct" rel4 <- rel_project( rel3, @@ -4071,7 +4071,7 @@ test_that("relational full_join(join_by(a)) order-preserving", { df2 <- data.frame(a = 2:5, b = 2) "full_join" - rel3 <- reldf_from_df(con, df, experimental = experimental) + rel3 <- rel_from_df(con, df2, experimental = experimental) "full_join" rel4 <- rel_set_alias(rel3, "rhs") "full_join" @@ -4212,7 +4212,7 @@ test_that("relational full_join(join_by(a)) order-enforcing", { df2 <- data.frame(a = 2:5, b = 2) "full_join" - rel3 <- reldf_from_df(con, df, experimental = experimental) + rel3 <- rel_from_df(con, df2, experimental = experimental) "full_join" rel4 <- rel_set_alias(rel3, "rhs") "full_join" @@ -4311,7 +4311,7 @@ test_that("relational inner_join(join_by(a)) order-preserving", { df2 <- data.frame(a = 2:5, b = 2) "inner_join" - rel3 <- reldf_from_df(con, df, experimental = experimental) + rel3 <- rel_from_df(con, df2, experimental = experimental) "inner_join" rel4 <- rel_set_alias(rel3, "rhs") "inner_join" @@ -4452,7 +4452,7 @@ test_that("relational inner_join(join_by(a)) order-enforcing", { df2 <- data.frame(a = 2:5, b = 2) "inner_join" - rel3 <- reldf_from_df(con, df, experimental = experimental) + rel3 <- rel_from_df(con, df2, experimental = experimental) "inner_join" rel4 <- rel_set_alias(rel3, "rhs") "inner_join" @@ -4550,7 +4550,7 @@ test_that("relational intersect() order-preserving", { df2 <- data.frame(a = 2:5, b = 2) "semi_join" - rel3 <- reldf_from_df(con, df, experimental = experimental) + rel3 <- rel_from_df(con, df2, experimental = experimental) "semi_join" rel4 <- rel_set_alias(rel3, "rhs") "semi_join" @@ -4720,9 +4720,9 @@ test_that("relational intersect() order-enforcing", { df2 <- data.frame(a = 2:5, b = 2) "intersect" - rel2 <- reldf_from_df(con, df, experimental = experimental) + rel2 <- rel_from_df(con, df2, experimental = experimental) "intersect" - rel3 <- reldf_set_intersect(rel1, rel) + rel3 <- rel_set_intersect(rel1, rel2) "arrange" rel4 <- rel_order(rel3, list(expr_reference("a"), expr_reference("b"))) rel4 @@ -4754,7 +4754,7 @@ test_that("relational left_join(join_by(a)) order-preserving", { df2 <- data.frame(a = 2:5, b = 2) "left_join" - rel3 <- reldf_from_df(con, df, experimental = experimental) + rel3 <- rel_from_df(con, df2, experimental = experimental) "left_join" rel4 <- rel_set_alias(rel3, "rhs") "left_join" @@ -4895,7 +4895,7 @@ test_that("relational left_join(join_by(a)) order-enforcing", { df2 <- data.frame(a = 2:5, b = 2) "left_join" - rel3 <- reldf_from_df(con, df, experimental = experimental) + rel3 <- rel_from_df(con, df2, experimental = experimental) "left_join" rel4 <- rel_set_alias(rel3, "rhs") "left_join" @@ -5040,7 +5040,7 @@ test_that("relational mutate(a + 1) order-preserving", { ) ) rel2 - out <- reldf_to_altrep(rel) + out <- rel_to_altrep(rel2) expect_identical( out, data.frame( @@ -5219,7 +5219,7 @@ test_that("relational mutate(c = a + 1) order-preserving", { ) ) rel2 - out <- reldf_to_altrep(rel) + out <- rel_to_altrep(rel2) expect_identical( out, data.frame( @@ -5278,7 +5278,7 @@ test_that("relational mutate(`if` = a + 1) order-preserving", { ) ) rel2 - out <- reldf_to_altrep(rel) + out <- rel_to_altrep(rel2) expect_identical( out, data.frame( @@ -5328,7 +5328,7 @@ test_that("relational mutate(sum(a)) order-preserving", { ) ) rel2 - out <- reldf_to_altrep(rel) + out <- rel_to_altrep(rel2) expect_identical( out, data.frame( @@ -5487,7 +5487,7 @@ test_that("relational mutate(mean(a)) order-preserving", { ) ) rel2 - out <- reldf_to_altrep(rel) + out <- rel_to_altrep(rel2) expect_identical( out, data.frame( @@ -5646,7 +5646,7 @@ test_that("relational mutate(sd(a)) order-preserving", { ) ) rel2 - out <- reldf_to_altrep(rel) + out <- rel_to_altrep(rel2) expect_identical( out, data.frame( @@ -5815,7 +5815,7 @@ test_that("relational mutate(lag(a)) order-preserving", { ) ) rel2 - out <- reldf_to_altrep(rel) + out <- rel_to_altrep(rel2) expect_identical( out, data.frame( @@ -5994,7 +5994,7 @@ test_that("relational mutate(lead(a)) order-preserving", { ) ) rel2 - out <- reldf_to_altrep(rel) + out <- rel_to_altrep(rel2) expect_identical( out, data.frame( @@ -6173,7 +6173,7 @@ test_that("relational mutate(lag(a, 2)) order-preserving", { ) ) rel2 - out <- reldf_to_altrep(rel) + out <- rel_to_altrep(rel2) expect_identical( out, data.frame( @@ -6352,7 +6352,7 @@ test_that("relational mutate(lead(a, 2)) order-preserving", { ) ) rel2 - out <- reldf_to_altrep(rel) + out <- rel_to_altrep(rel2) expect_identical( out, data.frame( @@ -6531,7 +6531,7 @@ test_that("relational mutate(lag(a, 4)) order-preserving", { ) ) rel2 - out <- reldf_to_altrep(rel) + out <- rel_to_altrep(rel2) expect_identical( out, data.frame( @@ -6710,7 +6710,7 @@ test_that("relational mutate(lead(a, 4)) order-preserving", { ) ) rel2 - out <- reldf_to_altrep(rel) + out <- rel_to_altrep(rel2) expect_identical( out, data.frame( @@ -6893,7 +6893,7 @@ test_that("relational mutate(lag(a, default = 0)) order-preserving", { ) ) rel2 - out <- reldf_to_altrep(rel) + out <- rel_to_altrep(rel2) expect_identical( out, data.frame( @@ -7080,7 +7080,7 @@ test_that("relational mutate(lead(a, default = 1000)) order-preserving", { ) ) rel2 - out <- reldf_to_altrep(rel) + out <- rel_to_altrep(rel2) expect_identical( out, data.frame( @@ -7253,7 +7253,7 @@ test_that("relational mutate(min(a)) order-preserving", { ) ) rel2 - out <- reldf_to_altrep(rel) + out <- rel_to_altrep(rel2) expect_identical( out, data.frame( @@ -7412,7 +7412,7 @@ test_that("relational mutate(max(a)) order-preserving", { ) ) rel2 - out <- reldf_to_altrep(rel) + out <- rel_to_altrep(rel2) expect_identical( out, data.frame( @@ -7571,7 +7571,7 @@ test_that("relational mutate(first(a)) order-preserving", { ) ) rel2 - out <- reldf_to_altrep(rel) + out <- rel_to_altrep(rel2) expect_identical( out, data.frame( @@ -7730,7 +7730,7 @@ test_that("relational mutate(last(a)) order-preserving", { ) ) rel2 - out <- reldf_to_altrep(rel) + out <- rel_to_altrep(rel2) expect_identical( out, data.frame( @@ -7905,7 +7905,7 @@ test_that("relational mutate(nth(a, 2)) order-preserving", { ) ) rel2 - out <- reldf_to_altrep(rel) + out <- rel_to_altrep(rel2) expect_identical( out, data.frame( @@ -8086,7 +8086,7 @@ test_that("relational mutate(a / b) order-preserving", { ) ) rel2 - out <- reldf_to_altrep(rel) + out <- rel_to_altrep(rel2) expect_identical( out, data.frame( @@ -8968,7 +8968,7 @@ test_that("relational mutate(d = a %in% NA_real_) order-preserving", { ) ) rel2 - out <- reldf_to_altrep(rel) + out <- rel_to_altrep(rel2) expect_identical( out, data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L), d = FALSE) @@ -9016,7 +9016,7 @@ test_that("relational mutate(d = a %in% NULL) order-preserving", { ) ) rel2 - out <- reldf_to_altrep(rel) + out <- rel_to_altrep(rel2) expect_identical( out, data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L), d = FALSE) @@ -9064,7 +9064,7 @@ test_that("relational mutate(d = a %in% integer()) order-preserving", { ) ) rel2 - out <- reldf_to_altrep(rel) + out <- rel_to_altrep(rel2) expect_identical( out, data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L), d = FALSE) @@ -9280,7 +9280,7 @@ test_that("relational mutate(d = row_number()) order-preserving", { ) ) rel2 - out <- reldf_to_altrep(rel) + out <- rel_to_altrep(rel2) expect_identical( out, data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L), d = 1:6) @@ -9438,7 +9438,7 @@ test_that("relational mutate(c = .data$b) order-preserving", { ) ) rel2 - out <- reldf_to_altrep(rel) + out <- rel_to_altrep(rel2) expect_identical( out, data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L), c = 2) @@ -9483,7 +9483,7 @@ test_that("relational mutate(d = NA) order-preserving", { ) ) rel2 - out <- reldf_to_altrep(rel) + out <- rel_to_altrep(rel2) expect_identical( out, data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L), d = NA) @@ -9531,7 +9531,7 @@ test_that("relational mutate(d = NA_integer_) order-preserving", { ) ) rel2 - out <- reldf_to_altrep(rel) + out <- rel_to_altrep(rel2) expect_identical( out, data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L), d = NA_integer_) @@ -9579,7 +9579,7 @@ test_that("relational mutate(d = NA_real_) order-preserving", { ) ) rel2 - out <- reldf_to_altrep(rel) + out <- rel_to_altrep(rel2) expect_identical( out, data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L), d = NA_real_) @@ -9627,7 +9627,7 @@ test_that("relational mutate(d = NA_character_) order-preserving", { ) ) rel2 - out <- reldf_to_altrep(rel) + out <- rel_to_altrep(rel2) expect_identical( out, data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L), d = NA_character_) @@ -9702,7 +9702,7 @@ test_that("relational mutate(d = if_else(a > 1, \"ok\", NA)) order-preserving", ) ) rel2 - out <- reldf_to_altrep(rel) + out <- rel_to_altrep(rel2) expect_identical( out, data.frame( @@ -9732,7 +9732,7 @@ test_that("relational mutate() order-enforcing", { list(expr_reference("a"), expr_reference("b"), expr_reference("g")) ) rel2 - out <- reldf_to_altrep(rel) + out <- rel_to_altrep(rel2) expect_identical( out, data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L)) @@ -13712,7 +13712,7 @@ test_that("relational relocate(g) order-preserving", { ) ) rel2 - out <- reldf_to_altrep(rel) + out <- rel_to_altrep(rel2) expect_identical( out, data.frame(g = c(1L, 2L, 2L, 3L, 3L, 3L), a = seq(1, 6, by = 1), b = 2) @@ -13751,7 +13751,7 @@ test_that("relational relocate(a) order-preserving", { ) ) rel2 - out <- reldf_to_altrep(rel) + out <- rel_to_altrep(rel2) expect_identical( out, data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L)) @@ -13790,7 +13790,7 @@ test_that("relational relocate(g, .before = b) order-preserving", { ) ) rel2 - out <- reldf_to_altrep(rel) + out <- rel_to_altrep(rel2) expect_identical( out, data.frame(a = seq(1, 6, by = 1), g = c(1L, 2L, 2L, 3L, 3L, 3L), b = 2) @@ -13829,7 +13829,7 @@ test_that("relational relocate(a:b, .after = g) order-preserving", { ) ) rel2 - out <- reldf_to_altrep(rel) + out <- rel_to_altrep(rel2) expect_identical( out, data.frame(g = c(1L, 2L, 2L, 3L, 3L, 3L), a = seq(1, 6, by = 1), b = 2) @@ -14048,7 +14048,7 @@ test_that("relational rename() order-preserving", { ) ) rel2 - out <- reldf_to_altrep(rel) + out <- rel_to_altrep(rel2) expect_identical( out, data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L)) @@ -14087,7 +14087,7 @@ test_that("relational rename(c = a) order-preserving", { ) ) rel2 - out <- reldf_to_altrep(rel) + out <- rel_to_altrep(rel2) expect_identical( out, data.frame(c = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L)) @@ -14204,7 +14204,7 @@ test_that("relational right_join(join_by(a)) order-preserving", { df2 <- data.frame(a = 2:5, b = 2) "right_join" - rel3 <- reldf_from_df(con, df, experimental = experimental) + rel3 <- rel_from_df(con, df2, experimental = experimental) "right_join" rel4 <- rel_set_alias(rel3, "rhs") "right_join" @@ -14344,7 +14344,7 @@ test_that("relational right_join(join_by(a)) order-enforcing", { df2 <- data.frame(a = 2:5, b = 2) "right_join" - rel3 <- reldf_from_df(con, df, experimental = experimental) + rel3 <- rel_from_df(con, df2, experimental = experimental) "right_join" rel4 <- rel_set_alias(rel3, "rhs") "right_join" @@ -14446,7 +14446,7 @@ test_that("relational select(a) order-preserving", { ) ) rel2 - out <- reldf_to_altrep(rel) + out <- rel_to_altrep(rel2) expect_identical( out, data.frame(a = seq(1, 6, by = 1)) @@ -14480,7 +14480,7 @@ test_that("relational select(-g) order-preserving", { ) ) rel2 - out <- reldf_to_altrep(rel) + out <- rel_to_altrep(rel2) expect_identical( out, data.frame(a = seq(1, 6, by = 1), b = 2) @@ -14519,7 +14519,7 @@ test_that("relational select(everything()) order-preserving", { ) ) rel2 - out <- reldf_to_altrep(rel) + out <- rel_to_altrep(rel2) expect_identical( out, data.frame(a = seq(1, 6, by = 1), b = 2, g = c(1L, 2L, 2L, 3L, 3L, 3L)) @@ -14550,7 +14550,7 @@ test_that("relational select(a) order-enforcing", { ) ) "arrange" - rel3 <- reldf_order(rel, list(expr_reference("a"))) + rel3 <- rel_order(rel2, list(expr_reference("a"))) rel3 out <- rel_to_altrep(rel3) expect_identical( @@ -14586,7 +14586,7 @@ test_that("relational select(-g) order-enforcing", { ) ) "arrange" - rel3 <- reldf_order(rel, list(expr_reference("a"), expr_reference("b"))) + rel3 <- rel_order(rel2, list(expr_reference("a"), expr_reference("b"))) rel3 out <- rel_to_altrep(rel3) expect_identical( @@ -14659,7 +14659,7 @@ test_that("relational semi_join(join_by(a)) order-preserving", { df2 <- data.frame(a = 2:5, b = 2) "semi_join" - rel3 <- reldf_from_df(con, df, experimental = experimental) + rel3 <- rel_from_df(con, df2, experimental = experimental) "semi_join" rel4 <- rel_set_alias(rel3, "rhs") "semi_join" @@ -14738,7 +14738,7 @@ test_that("relational semi_join(join_by(a)) order-enforcing", { df2 <- data.frame(a = 2:5, b = 2) "semi_join" - rel3 <- reldf_from_df(con, df, experimental = experimental) + rel3 <- rel_from_df(con, df2, experimental = experimental) "semi_join" rel4 <- rel_set_alias(rel3, "rhs") "semi_join" @@ -14780,7 +14780,7 @@ test_that("relational setdiff() order-preserving", { df2 <- data.frame(a = 2:5, b = 2) "anti_join" - rel3 <- reldf_from_df(con, df, experimental = experimental) + rel3 <- rel_from_df(con, df2, experimental = experimental) "anti_join" rel4 <- rel_set_alias(rel3, "rhs") "anti_join" @@ -14950,9 +14950,9 @@ test_that("relational setdiff() order-enforcing", { df2 <- data.frame(a = 2:5, b = 2) "setdiff" - rel2 <- reldf_from_df(con, df, experimental = experimental) + rel2 <- rel_from_df(con, df2, experimental = experimental) "setdiff" - rel3 <- reldf_set_diff(rel1, rel) + rel3 <- rel_set_diff(rel1, rel2) "arrange" rel4 <- rel_order(rel3, list(expr_reference("a"), expr_reference("b"))) rel4 @@ -14988,7 +14988,7 @@ test_that("relational summarise(c = mean(a)) order-preserving", { ) ) "summarise" - rel3 <- reldf_distinct(rel) + rel3 <- rel_distinct(rel2) rel3 out <- rel_to_altrep(rel3) expect_identical( @@ -15182,7 +15182,7 @@ test_that("relational summarise(c = 1) order-preserving", { ) ) "summarise" - rel3 <- reldf_distinct(rel) + rel3 <- rel_distinct(rel2) rel3 out <- rel_to_altrep(rel3) expect_identical( @@ -15398,7 +15398,7 @@ test_that("relational summarise(n = n(), n = n() + 1L) order-preserving", { ) ) "summarise" - rel3 <- reldf_distinct(rel) + rel3 <- rel_distinct(rel2) rel3 out <- rel_to_altrep(rel3) expect_identical( @@ -15432,7 +15432,7 @@ test_that("relational summarise(c = mean(a)) order-enforcing", { ) ) "summarise" - rel3 <- reldf_distinct(rel) + rel3 <- rel_distinct(rel2) "arrange" rel4 <- rel_order(rel3, list(expr_reference("c"))) rel4 @@ -15466,7 +15466,7 @@ test_that("relational summarise(c = mean(a), .by = b) order-enforcing", { ) ) "arrange" - rel3 <- reldf_order(rel, list(expr_reference("b"), expr_reference("c"))) + rel3 <- rel_order(rel2, list(expr_reference("b"), expr_reference("c"))) rel3 out <- rel_to_altrep(rel3) expect_identical( @@ -15498,7 +15498,7 @@ test_that("relational summarise(c = mean(a), .by = g) order-enforcing", { ) ) "arrange" - rel3 <- reldf_order(rel, list(expr_reference("g"), expr_reference("c"))) + rel3 <- rel_order(rel2, list(expr_reference("g"), expr_reference("c"))) rel3 out <- rel_to_altrep(rel3) expect_identical( @@ -15534,7 +15534,7 @@ test_that("relational summarise(c = 1) order-enforcing", { ) ) "summarise" - rel3 <- reldf_distinct(rel) + rel3 <- rel_distinct(rel2) "arrange" rel4 <- rel_order(rel3, list(expr_reference("c"))) rel4 @@ -15572,7 +15572,7 @@ test_that("relational summarise(c = 1, .by = g) order-enforcing", { ) ) "arrange" - rel3 <- reldf_order(rel, list(expr_reference("g"), expr_reference("c"))) + rel3 <- rel_order(rel2, list(expr_reference("g"), expr_reference("c"))) rel3 out <- rel_to_altrep(rel3) expect_identical( @@ -15615,7 +15615,7 @@ test_that("relational summarise(n = n(), n = n() + 1L, .by = g) order-enforcing" ) ) "arrange" - rel3 <- reldf_order(rel, list(expr_reference("g"), expr_reference("n"))) + rel3 <- rel_order(rel2, list(expr_reference("g"), expr_reference("n"))) rel3 out <- rel_to_altrep(rel3) expect_identical( @@ -15658,7 +15658,7 @@ test_that("relational summarise(n = n(), n = n() + 1L) order-enforcing", { ) ) "summarise" - rel3 <- reldf_distinct(rel) + rel3 <- rel_distinct(rel2) "arrange" rel4 <- rel_order(rel3, list(expr_reference("n"))) rel4 @@ -15689,7 +15689,7 @@ test_that("relational symdiff() order-preserving", { df2 <- data.frame(a = 2:5, b = 2) "anti_join" - rel3 <- reldf_from_df(con, df, experimental = experimental) + rel3 <- rel_from_df(con, df2, experimental = experimental) "anti_join" rel4 <- rel_set_alias(rel3, "rhs") "anti_join" @@ -15946,9 +15946,9 @@ test_that("relational symdiff() order-enforcing", { df2 <- data.frame(a = 2:5, b = 2) "symdiff" - rel2 <- reldf_from_df(con, df, experimental = experimental) + rel2 <- rel_from_df(con, df2, experimental = experimental) "symdiff" - rel3 <- reldf_set_symdiff(rel1, rel) + rel3 <- rel_set_symdiff(rel1, rel2) "arrange" rel4 <- rel_order(rel3, list(expr_reference("a"), expr_reference("b"))) rel4 @@ -15985,7 +15985,7 @@ test_that("relational tally() order-preserving", { ) ) "summarise" - rel3 <- reldf_distinct(rel) + rel3 <- rel_distinct(rel2) rel3 out <- rel_to_altrep(rel3) expect_identical( @@ -16020,7 +16020,7 @@ test_that("relational tally() order-enforcing", { ) ) "summarise" - rel3 <- reldf_distinct(rel) + rel3 <- rel_distinct(rel2) "arrange" rel4 <- rel_order(rel3, list(expr_reference("n"))) rel4 @@ -16065,7 +16065,7 @@ test_that("relational transmute(c = a + 1) order-preserving", { ) ) rel2 - out <- reldf_to_altrep(rel) + out <- rel_to_altrep(rel2) expect_identical( out, data.frame(c = seq(2, 7, by = 1)) @@ -16094,7 +16094,7 @@ test_that("relational transmute(row = a) order-preserving", { ) ) rel2 - out <- reldf_to_altrep(rel) + out <- rel_to_altrep(rel2) expect_identical( out, data.frame(row = seq(1, 6, by = 1)) @@ -16135,7 +16135,7 @@ test_that("relational transmute(c = a + 1) order-enforcing", { ) ) "arrange" - rel3 <- reldf_order(rel, list(expr_reference("c"))) + rel3 <- rel_order(rel2, list(expr_reference("c"))) rel3 out <- rel_to_altrep(rel3) expect_identical( @@ -16166,7 +16166,7 @@ test_that("relational transmute(row = a) order-enforcing", { ) ) "arrange" - rel3 <- reldf_order(rel, list(expr_reference("row"))) + rel3 <- rel_order(rel2, list(expr_reference("row"))) rel3 out <- rel_to_altrep(rel3) expect_identical( @@ -16190,7 +16190,7 @@ test_that("relational union() order-preserving", { df2 <- data.frame(a = 2:5, b = 2) "union_all" - rel2 <- reldf_from_df(con, df, experimental = experimental) + rel2 <- rel_from_df(con, df2, experimental = experimental) "union_all" rel3 <- rel_project( rel1, @@ -16370,7 +16370,7 @@ test_that("relational union() order-preserving", { ) ) rel12 - out <- reldf_to_altrep(rel1) + out <- rel_to_altrep(rel12) expect_identical( out, data.frame(a = 1:5, b = 2) @@ -16392,9 +16392,9 @@ test_that("relational union() order-enforcing", { df2 <- data.frame(a = 2:5, b = 2) "union_all" - rel2 <- reldf_from_df(con, df, experimental = experimental) + rel2 <- rel_from_df(con, df2, experimental = experimental) "union_all" - rel3 <- reldf_union_all(rel1, rel) + rel3 <- rel_union_all(rel1, rel2) "distinct" rel4 <- rel_distinct(rel3) "arrange" @@ -16422,7 +16422,7 @@ test_that("relational union_all() order-preserving", { df2 <- data.frame(a = 2:5, b = 2) "union_all" - rel2 <- reldf_from_df(con, df, experimental = experimental) + rel2 <- rel_from_df(con, df2, experimental = experimental) "union_all" rel3 <- rel_project( rel1, @@ -16529,9 +16529,9 @@ test_that("relational union_all() order-enforcing", { df2 <- data.frame(a = 2:5, b = 2) "union_all" - rel2 <- reldf_from_df(con, df, experimental = experimental) + rel2 <- rel_from_df(con, df2, experimental = experimental) "union_all" - rel3 <- reldf_union_all(rel1, rel) + rel3 <- rel_union_all(rel1, rel2) "arrange" rel4 <- rel_order(rel3, list(expr_reference("a"), expr_reference("b"))) rel4 diff --git a/tests/testthat/test-relational.R b/tests/testthat/test-relational.R index 035d70235..c59ae1bb9 100644 --- a/tests/testthat/test-relational.R +++ b/tests/testthat/test-relational.R @@ -146,7 +146,7 @@ test_that("we can cast R strings to DuckDB strings", { # many rounds yay df2 <- df for (i in 1:10) { - df2 <- as.data.frame.duckdb_relation(reldf_from_df(con, df)) + df2 <- as.data.frame.duckdb_relation(rel_from_df(con, df2)) expect_equivalent(df, df2) } @@ -154,7 +154,7 @@ test_that("we can cast R strings to DuckDB strings", { for (i in 1:10) { df2 <- as.data.frame( rel_sql( - reldf_from_df(con, df), + rel_from_df(con, df2), "SELECT s::string s FROM _" ) ) @@ -223,11 +223,11 @@ test_that("rel_order() sorts NAs last", { test_that("Inner join returns all inner relations", { dbExecute(con, "CREATE OR REPLACE MACRO eq(a, b) AS a = b") - left <- reldf_from_df(con, data.frame(left_a = c(1, , 3), left_b = c(1, 1, 2))) + left <- rel_from_df(con, data.frame(left_a = c(1, 2, 3), left_b = c(1, 1, 2))) right <- rel_from_df(con, data.frame(right_b = c(1, 3), right_c = c(4, 5))) cond <- list(expr_function("eq", list(expr_reference("left_b"), expr_reference("right_b")))) rel2 <- rel_join(left, right, cond, "inner") - reldf_df <- rel_to_altrep(rel) + rel_df <- rel_to_altrep(rel2) dim(rel_df) expected_result <- data.frame(left_a = c(1, 2), left_b = c(1, 1), right_b = c(1, 1), right_c = c(4, 4)) expect_equal(rel_df, expected_result) @@ -235,11 +235,11 @@ test_that("Inner join returns all inner relations", { test_that("Left join returns all left relations", { dbExecute(con, "CREATE OR REPLACE MACRO eq(a, b) AS a = b") - left <- reldf_from_df(con, data.frame(left_a = c(1, , 3), left_b = c(1, 1, 2))) + left <- rel_from_df(con, data.frame(left_a = c(1, 2, 3), left_b = c(1, 1, 2))) right <- rel_from_df(con, data.frame(right_b = c(1))) cond <- list(expr_function("eq", list(expr_reference("left_b"), expr_reference("right_b")))) rel2 <- rel_join(left, right, cond, "left") - reldf_df <- rel_to_altrep(rel) + rel_df <- rel_to_altrep(rel2) dim(rel_df) expected_result <- data.frame(left_a = c(1, 2, 3), left_b = c(1, 1, 2), right_b = c(1, 1, NA)) expect_equal(rel_df, expected_result) @@ -248,10 +248,10 @@ test_that("Left join returns all left relations", { test_that("Right join returns all right relations", { dbExecute(con, "CREATE OR REPLACE MACRO eq(a, b) AS a = b") left <- rel_from_df(con, data.frame(left_b = c(1))) - right <- reldf_from_df(con, data.frame(right_a = c(1, , 3), right_b = c(1, 1, 2))) + right <- rel_from_df(con, data.frame(right_a = c(1, 2, 3), right_b = c(1, 1, 2))) cond <- list(expr_function("eq", list(expr_reference("left_b"), expr_reference("right_b")))) rel2 <- rel_join(left, right, cond, "right") - reldf_df <- rel_to_altrep(rel) + rel_df <- rel_to_altrep(rel2) dim(rel_df) expected_result <- data.frame(left_b = c(1, 1, NA), right_a = c(1, 2, 3), right_b = c(1, 1, 2)) expect_equal(rel_df, expected_result) @@ -259,11 +259,11 @@ test_that("Right join returns all right relations", { test_that("Full join returns all outer relations", { dbExecute(con, "CREATE OR REPLACE MACRO eq(a, b) AS a = b") - left <- reldf_from_df(con, data.frame(left_a = c(1, , 5), left_b = c(4, 5, 6))) - right <- reldf_from_df(con, data.frame(right_a = c(1, , 3), right_b = c(1, 1, 2))) + left <- rel_from_df(con, data.frame(left_a = c(1, 2, 5), left_b = c(4, 5, 6))) + right <- rel_from_df(con, data.frame(right_a = c(1, 2, 3), right_b = c(1, 1, 2))) cond <- list(expr_function("eq", list(expr_reference("left_a"), expr_reference("right_a")))) rel2 <- rel_join(left, right, cond, "outer") - reldf_df <- rel_to_altrep(rel) + rel_df <- rel_to_altrep(rel2) expected_result <- data.frame( left_a = c(1, 2, 5, NA), @@ -278,7 +278,7 @@ test_that("Full join returns all outer relations", { }) test_that("cross join works", { - left <- reldf_from_df(con, data.frame(left_a = c(1, , 3), left_b = c(1, 1, 2))) + left <- rel_from_df(con, data.frame(left_a = c(1, 2, 3), left_b = c(1, 1, 2))) right <- rel_from_df(con, data.frame(right_a = c(1, 4, 5), right_b = c(7, 8, 9))) cross <- rel_join(left, right, list(), "cross") order_by <- rel_order(cross, list(expr_reference("right_a"), expr_reference("right_a"))) @@ -295,11 +295,11 @@ test_that("cross join works", { test_that("semi join works", { left <- rel_from_df(con, data.frame(left_b = c(1, 5, 6))) - right <- reldf_from_df(con, data.frame(right_a = c(1, , 3), right_b = c(1, 1, 2))) + right <- rel_from_df(con, data.frame(right_a = c(1, 2, 3), right_b = c(1, 1, 2))) cond <- list(expr_function("eq", list(expr_reference("left_b"), expr_reference("right_a")))) # select * from left semi join right on (left_b = right_a) rel2 <- rel_join(left, right, cond, "semi") - reldf_df <- rel_to_altrep(rel) + rel_df <- rel_to_altrep(rel2) dim(rel_df) expected_result <- data.frame(left_b = c(1)) expect_equal(rel_df, expected_result) @@ -308,18 +308,18 @@ test_that("semi join works", { test_that("anti join works", { left <- rel_from_df(con, data.frame(left_b = c(1, 5, 6))) - right <- reldf_from_df(con, data.frame(right_a = c(1, , 3), right_b = c(1, 1, 2))) + right <- rel_from_df(con, data.frame(right_a = c(1, 2, 3), right_b = c(1, 1, 2))) cond <- list(expr_function("eq", list(expr_reference("left_b"), expr_reference("right_a")))) # select * from left anti join right on (left_b = right_a) rel2 <- rel_join(left, right, cond, "anti") - reldf_df <- rel_to_altrep(rel) + rel_df <- rel_to_altrep(rel2) dim(rel_df) expected_result <- data.frame(left_b = c(5, 6)) expect_equal(rel_df, expected_result) }) test_that("Union all does not immediately materialize", { - test_df_a <- reldf_from_df(con, data.frame(a = c("1", ""), b = c("3", "4"))) + test_df_a <- rel_from_df(con, data.frame(a = c("1", "2"), b = c("3", "4"))) test_df_b <- rel_from_df(con, data.frame(a = c("5", "6"), b = c("7", "8"))) rel <- rel_union_all(test_df_a, test_df_b) rel_df <- rel_to_altrep(rel) @@ -329,7 +329,7 @@ test_that("Union all does not immediately materialize", { }) test_that("Union all has the correct values", { - test_df_a <- reldf_from_df(con, data.frame(a = c("1", ""), b = c("3", "4"))) + test_df_a <- rel_from_df(con, data.frame(a = c("1", "2"), b = c("3", "4"))) test_df_b <- rel_from_df(con, data.frame(a = c("5", "6"), b = c("7", "8"))) rel <- rel_union_all(test_df_a, test_df_b) order_by_rel <- rel_order(rel, list(expr_reference("a"), expr_reference("b"))) @@ -342,9 +342,9 @@ test_that("Union all has the correct values", { }) test_that("Union all keeps duplicates", { - test_df_a2 <- reldf_from_df(con, data.frame(a = c("1", ""), b = c("3", "4"))) - test_df_b2 <- reldf_from_df(con, data.frame(a = c("1", ""), b = c("3", "4"))) - rel <- reldf_union_all(test_df_a, test_df_b2) + test_df_a2 <- rel_from_df(con, data.frame(a = c("1", "2"), b = c("3", "4"))) + test_df_b2 <- rel_from_df(con, data.frame(a = c("1", "2"), b = c("3", "4"))) + rel <- rel_union_all(test_df_a2, test_df_b2) order_by_rel <- rel_order(rel, list(expr_reference("a"), expr_reference("b"))) rel_df <- rel_to_altrep(order_by_rel) dim(rel_df) @@ -355,11 +355,11 @@ test_that("Union all keeps duplicates", { test_that("Inner join returns all inner relations", { dbExecute(con, "CREATE OR REPLACE MACRO eq(a, b) AS a = b") - left <- reldf_from_df(con, data.frame(left_a = c(1, , 3), left_b = c(1, 1, 2))) + left <- rel_from_df(con, data.frame(left_a = c(1, 2, 3), left_b = c(1, 1, 2))) right <- rel_from_df(con, data.frame(right_b = c(1, 3), right_c = c(4, 5))) cond <- list(expr_function("eq", list(expr_reference("left_b"), expr_reference("right_b")))) rel2 <- rel_join(left, right, cond, "inner") - reldf_df <- rel_to_altrep(rel) + rel_df <- rel_to_altrep(rel2) dim(rel_df) expected_result <- data.frame(left_a = c(1, 2), left_b = c(1, 1), right_b = c(1, 1), right_c = c(4, 4)) expect_equal(rel_df, expected_result) @@ -367,10 +367,10 @@ test_that("Inner join returns all inner relations", { test_that("ASOF join works", { dbExecute(con, "CREATE OR REPLACE MACRO gte(a, b) AS a >= b") - test_df1 <- reldf_from_df(con, data.frame(ts = c(1, , 3, 4, 5, 6, 7, 8, 9))) - test_df2 <- reldf_from_df(con, data.frame(event_ts = c(1, 3, 6, 8), event_id = c(0, 1, , 3))) + test_df1 <- rel_from_df(con, data.frame(ts = c(1, 2, 3, 4, 5, 6, 7, 8, 9))) + test_df2 <- rel_from_df(con, data.frame(event_ts = c(1, 3, 6, 8), event_id = c(0, 1, 2, 3))) cond <- list(expr_function("gte", list(expr_reference("ts"), expr_reference("event_ts")))) - rel <- reldf_join(test_df1, test_df, cond, join_ref_type = "asof") + rel <- rel_join(test_df1, test_df2, cond, join_ref_type = "asof") rel_proj <- rel_project(rel, list(expr_reference("ts"), expr_reference("event_id"))) order <- rel_order(rel_proj, list(expr_reference("ts"))) rel_df <- rel_to_altrep(order) @@ -380,10 +380,10 @@ test_that("ASOF join works", { test_that("LEFT ASOF join works", { dbExecute(con, "CREATE OR REPLACE MACRO gte(a, b) AS a >= b") - test_df1 <- reldf_from_df(con, data.frame(ts = c(0, 1, , 3, 4, 5, 6, 7, 8, 9))) - test_df2 <- reldf_from_df(con, data.frame(event_ts = c(, 4, 6, 8), event_id = c(0, 1, 2, 3))) + test_df1 <- rel_from_df(con, data.frame(ts = c(0, 1, 2, 3, 4, 5, 6, 7, 8, 9))) + test_df2 <- rel_from_df(con, data.frame(event_ts = c(2, 4, 6, 8), event_id = c(0, 1, 2, 3))) cond <- list(expr_function("gte", list(expr_reference("ts"), expr_reference("event_ts")))) - rel <- reldf_join(test_df1, test_df, cond, join = "left", join_ref_type = "asof") + rel <- rel_join(test_df1, test_df2, cond, join = "left", join_ref_type = "asof") rel_proj <- rel_project(rel, list(expr_reference("ts"), expr_reference("event_ts"), expr_reference("event_id"))) order <- rel_order(rel_proj, list(expr_reference("ts"))) rel_df <- rel_to_altrep(order) @@ -392,9 +392,9 @@ test_that("LEFT ASOF join works", { }) test_that("Positional cross join works", { - test_df1 <- reldf_from_df(con, data.frame(a = c(11, 1, 13), b = c(1, 2, 3))) - test_df2 <- reldf_from_df(con, data.frame(c = c(11, 1), d = c(1, 2))) - rel <- reldf_join(test_df1, test_df, list(), join = "cross", join_ref_type = "positional") + test_df1 <- rel_from_df(con, data.frame(a = c(11, 12, 13), b = c(1, 2, 3))) + test_df2 <- rel_from_df(con, data.frame(c = c(11, 12), d = c(1, 2))) + rel <- rel_join(test_df1, test_df2, list(), join = "cross", join_ref_type = "positional") rel_df <- rel_to_altrep(rel) expected_result <- data.frame(a = c(11, 12, 13), b = c(1, 2, 3), c = c(11, 12, NA), d = c(1, 2, NA)) expect_equal(expected_result, rel_df) @@ -402,10 +402,10 @@ test_that("Positional cross join works", { test_that("regular positional join works", { dbExecute(con, "CREATE OR REPLACE MACRO eq(a, b) AS a = b") - test_df1 <- reldf_from_df(con, data.frame(a = c(11, 1, 13), b = c(1, 2, 3))) - test_df2 <- reldf_from_df(con, data.frame(c = c(11, 1, 14, 11), d = c(4, 5, 6, 8))) + test_df1 <- rel_from_df(con, data.frame(a = c(11, 12, 13), b = c(1, 2, 3))) + test_df2 <- rel_from_df(con, data.frame(c = c(11, 12, 14, 11), d = c(4, 5, 6, 8))) cond <- expr_function("eq", list(expr_reference("a"), expr_reference("c"))) - rel <- reldf_join(test_df1, test_df, list(cond), join_ref_type = "positional") + rel <- rel_join(test_df1, test_df2, list(cond), join_ref_type = "positional") rel_df <- rel_to_altrep(rel) expected_result <- data.frame(a = c(11, 12), b = c(1, 2), c = c(11, 12), d = c(4, 5)) expect_equal(expected_result, rel_df) @@ -413,27 +413,27 @@ test_that("regular positional join works", { test_that("Invalid asof join condition throws error", { dbExecute(con, "CREATE OR REPLACE MACRO neq(a, b) AS a <> b") - test_df1 <- reldf_from_df(con, data.frame(ts = c(1, , 3, 4, 5, 6, 7, 8, 9))) - test_df2 <- reldf_from_df(con, data.frame(begin = c(1, 3, 6, 8), value = c(0, 1, , 3))) + test_df1 <- rel_from_df(con, data.frame(ts = c(1, 2, 3, 4, 5, 6, 7, 8, 9))) + test_df2 <- rel_from_df(con, data.frame(begin = c(1, 3, 6, 8), value = c(0, 1, 2, 3))) cond <- list(expr_function("neq", list(expr_reference("ts"), expr_reference("begin")))) - expect_error(reldf_join(test_df1, test_df, cond, join_ref_type = "asof"), "Binder") + expect_error(rel_join(test_df1, test_df2, cond, join_ref_type = "asof"), "Binder") }) test_that("multiple inequality conditions for asof join throws error", { dbExecute(con, "CREATE OR REPLACE MACRO gte(a, b) AS a >= b") - test_df1 <- reldf_from_df(con, data.frame(ts = c(1, , 3, 4, 5, 6, 7, 8, 9))) - test_df2 <- reldf_from_df(con, data.frame(begin = c(1, 3, 6, 8), value = c(0, 1, , 3))) + test_df1 <- rel_from_df(con, data.frame(ts = c(1, 2, 3, 4, 5, 6, 7, 8, 9))) + test_df2 <- rel_from_df(con, data.frame(begin = c(1, 3, 6, 8), value = c(0, 1, 2, 3))) cond1 <- expr_function("gte", list(expr_reference("ts"), expr_reference("begin"))) cond2 <- expr_function("gte", list(expr_reference("ts"), expr_reference("value"))) conds <- list(cond1, cond2) - expect_error(reldf_join(test_df1, test_df, conds, join_ref_type = "asof"), "Binder") + expect_error(rel_join(test_df1, test_df2, conds, join_ref_type = "asof"), "Binder") }) test_that("Inequality joins work", { dbExecute(con, "CREATE OR REPLACE MACRO gte(a, b) AS a >= b") - timing_df <- reldf_from_df(con, data.frame(ts = c(1, , 3, 4, 5, 6))) - events_df <- reldf_from_df(con, data.frame(event_ts = c(1, 3, 6, 8), event_id = c(0, 1, , 3))) + timing_df <- rel_from_df(con, data.frame(ts = c(1, 2, 3, 4, 5, 6))) + events_df <- rel_from_df(con, data.frame(event_ts = c(1, 3, 6, 8), event_id = c(0, 1, 2, 3))) cond <- list(expr_function("gte", list(expr_reference("ts"), expr_reference("event_ts")))) rel <- rel_inner_join(timing_df, events_df, cond) rel_proj <- rel_project(rel, list(expr_reference("ts"), expr_reference("event_ts"))) @@ -447,8 +447,8 @@ test_that("Inequality joins work", { test_that("Inequality join works to perform between operation", { dbExecute(con, "CREATE OR REPLACE MACRO gt(a, b) AS a > b") dbExecute(con, "CREATE OR REPLACE MACRO lt(a, b) AS a < b") - timing_df <- reldf_from_df(con, data.frame(ts = c(1, , 3, 4, 5, 6, 7, 8, 9))) - events_df <- reldf_from_df(con, data.frame(event_ts = c(1, 3, 6, 8), event_id = c(0, 1, , 3))) + timing_df <- rel_from_df(con, data.frame(ts = c(1, 2, 3, 4, 5, 6, 7, 8, 9))) + events_df <- rel_from_df(con, data.frame(event_ts = c(1, 3, 6, 8), event_id = c(0, 1, 2, 3))) lead <- expr_function("lead", list(expr_reference("event_ts"))) window_lead <- expr_window(lead, offset_expr = expr_constant(1)) expr_set_alias(window_lead, "lead") @@ -467,24 +467,24 @@ test_that("Inequality join works to perform between operation", { # nobody should do this in reality. It's a pretty dumb idea test_that("we can union the same relation to itself", { - test_df_a2 <- reldf_from_df(con, data.frame(a = c("1", ""), b = c("3", "4"))) - rel <- reldf_union_all(test_df_a, test_df_a2) + test_df_a2 <- rel_from_df(con, data.frame(a = c("1", "2"), b = c("3", "4"))) + rel <- rel_union_all(test_df_a2, test_df_a2) rel_df <- rel_to_altrep(rel) expected_result <- data.frame(a = c("1", "2", "1", "2"), b = c("3", "4", "3", "4")) expect_equal(rel_df, expected_result) }) test_that("we throw an error when attempting to union all relations that are not compatible", { - test_df_a2 <- reldf_from_df(con, data.frame(a = c("1", ""), b = c("3", "4"))) - test_df_b2 <- reldf_from_df(con, data.frame(a = c("1", ""), b = c("3", "4"), c = c("5", "6"))) + test_df_a2 <- rel_from_df(con, data.frame(a = c("1", "2"), b = c("3", "4"))) + test_df_b2 <- rel_from_df(con, data.frame(a = c("1", "2"), b = c("3", "4"), c = c("5", "6"))) # The two data frames have different dimensions, therefore you get a binding error. - expect_error(reldf_union_all(test_df_a, test_df_b2), "Binder") + expect_error(rel_union_all(test_df_a2, test_df_b2), "Binder") }) test_that("A union with different column types casts to the richer type", { test_df_a1 <- rel_from_df(con, data.frame(a = c(1))) test_df_a2 <- rel_from_df(con, data.frame(a = c("1"))) - rel <- reldf_union_all(test_df_a1, test_df_a) + rel <- rel_union_all(test_df_a1, test_df_a2) res <- rapi_rel_to_df(rel) expected <- data.frame(a = c("1.0", "1")) expect_equal(class(res$a), class(expected$a)) @@ -493,7 +493,7 @@ test_that("A union with different column types casts to the richer type", { }) test_that("Set Intersect returns set intersection", { - test_df_a <- reldf_from_df(con, data.frame(a = c(1, ), b = c(3, 4))) + test_df_a <- rel_from_df(con, data.frame(a = c(1, 2), b = c(3, 4))) test_df_b <- rel_from_df(con, data.frame(a = c(1, 6), b = c(3, 8))) rel <- rel_set_intersect(test_df_a, test_df_b) ordered_rel <- rel_order(rel, list(expr_reference("a"))) @@ -513,14 +513,14 @@ test_that("Set intersect casts columns to the richer type", { expect_equal(class(df2$x), "numeric") out <- rel_set_intersect( rel_from_df(con, df1), - reldf_from_df(con, df) + rel_from_df(con, df2) ) out_df <- rapi_rel_to_df(out) expect_equal(class(out_df$x), "numeric") }) test_that("Set Diff returns the set difference", { - test_df_a <- reldf_from_df(con, data.frame(a = c(1, ), b = c(3, 4))) + test_df_a <- rel_from_df(con, data.frame(a = c(1, 2), b = c(3, 4))) test_df_b <- rel_from_df(con, data.frame(a = c(1, 6), b = c(3, 8))) rel <- rel_set_diff(test_df_a, test_df_b) rel_df <- rel_to_altrep(rel) @@ -531,7 +531,7 @@ test_that("Set Diff returns the set difference", { }) test_that("Symmetric difference returns the symmetric difference", { - test_df_a <- reldf_from_df(con, data.frame(a = c(1, ), b = c(3, 4))) + test_df_a <- rel_from_df(con, data.frame(a = c(1, 2), b = c(3, 4))) test_df_b <- rel_from_df(con, data.frame(a = c(1, 6), b = c(3, 8))) rel <- rel_set_symdiff(test_df_a, test_df_b) ordered_rel <- rel_order(rel, list(expr_reference("a"), expr_reference("b"))) @@ -543,7 +543,7 @@ test_that("Symmetric difference returns the symmetric difference", { }) test_that("rel aggregate with no groups but a sum over a column, sums the column", { - reldf_a <- rel_from_df(con, data.frame(a = c(1, ), b = c(3, 4))) + rel_a <- rel_from_df(con, data.frame(a = c(1, 2), b = c(3, 4))) aggrs <- list(sum = expr_function("sum", list(expr_reference("a")))) res <- rel_aggregate(rel_a, list(), aggrs) rel_df <- rel_to_altrep(res) @@ -552,7 +552,7 @@ test_that("rel aggregate with no groups but a sum over a column, sums the column }) test_that("rel aggregate with groups and aggregate function works", { - reldf_a <- rel_from_df(con, data.frame(a = c(1, , 5, 5), b = c(3, 3, 4, 4))) + rel_a <- rel_from_df(con, data.frame(a = c(1, 2, 5, 5), b = c(3, 3, 4, 4))) aggrs <- list(sum = expr_function("sum", list(expr_reference("a")))) rel_b <- rel_aggregate(rel_a, list(expr_reference("b")), aggrs) res <- rel_order(rel_b, list(expr_reference("b"))) @@ -563,7 +563,7 @@ test_that("rel aggregate with groups and aggregate function works", { test_that("Window sum expression function test works", { # select j, i, sum(i) over (partition by j) from a order by 1,2 - reldf_a <- rel_from_df(con, data.frame(a = c(1:8), b = c(1, 1, , 2, 3, 3, 4, 4))) + rel_a <- rel_from_df(con, data.frame(a = c(1:8), b = c(1, 1, 2, 2, 3, 3, 4, 4))) sum_func <- expr_function("sum", list(expr_reference("a"))) aggrs <- expr_window(sum_func, partitions = list(expr_reference("b"))) expr_set_alias(aggrs, "window_result") @@ -576,7 +576,7 @@ test_that("Window sum expression function test works", { test_that("Window count function works", { # select a, b, count(b) over (partition by a) from a order by a - reldf_a <- rel_from_df(con, data.frame(a = c(1:8), b = c(1, 1, , 2, 3, 3, 4, 4))) + rel_a <- rel_from_df(con, data.frame(a = c(1:8), b = c(1, 1, 2, 2, 3, 3, 4, 4))) count_func <- expr_function("count", list(expr_reference("a"))) count <- expr_window(count_func, partitions = list(expr_reference("b"))) expr_set_alias(count, "window_result") @@ -588,7 +588,7 @@ test_that("Window count function works", { test_that("Window avg function works", { # select a, b, avg(b) over (partition by a) from a order by a - reldf_a <- rel_from_df(con, data.frame(a = c(1:8), b = c(1, 1, , 2, 3, 3, 4, 4))) + rel_a <- rel_from_df(con, data.frame(a = c(1:8), b = c(1, 1, 2, 2, 3, 3, 4, 4))) avg_func <- expr_function("avg", list(expr_reference("a"))) avg_window <- expr_window(avg_func, partitions = list(expr_reference("b"))) expr_set_alias(avg_window, "window_result") @@ -601,7 +601,7 @@ test_that("Window avg function works", { test_that("Window sum with Partition, order, and window boundaries works", { # SUM(x) OVER (partition by b ROWS BETWEEN 3 PRECEDING AND CURRENT ROW) - reldf_a <- rel_from_df(con, data.frame(a = c(1:8), b = c(1, 1, 1, 1, , 2, 2, 2))) + rel_a <- rel_from_df(con, data.frame(a = c(1:8), b = c(1, 1, 1, 1, 2, 2, 2, 2))) partitions <- list(expr_reference("b")) order_by_a <- list(rel_order(rel_a, list(expr_reference("a")))) sum_func <- expr_function("sum", list(expr_reference("a"))) @@ -622,7 +622,7 @@ test_that("Window sum with Partition, order, and window boundaries works", { test_that("Window boundaries boundaries are CaSe INsenSItive", { # SUM(x) OVER (partition by b ROWS BETWEEN 3 PRECEDING AND CURRENT ROW) - reldf_a <- rel_from_df(con, data.frame(a = c(1:8), b = c(1, 1, 1, 1, , 2, 2, 2))) + rel_a <- rel_from_df(con, data.frame(a = c(1:8), b = c(1, 1, 1, 1, 2, 2, 2, 2))) partitions <- list(expr_reference("b")) order_by_a <- list(rel_order(rel_a, list(expr_reference("a")))) sum_func <- expr_function("sum", list(expr_reference("a"))) @@ -645,7 +645,7 @@ test_that("Window avg with a filter expression and partition works", { # select a, b, avg(a) FILTER (WHERE x % 2 = 0) over (partition by b) DBI::dbExecute(con, "CREATE OR REPLACE MACRO mod(a, b) as a % b") DBI::dbExecute(con, "CREATE OR REPLACE MACRO eq(a, b) as a = b") - reldf_a <- rel_from_df(con, data.frame(a = c(1:8), b = c(1, 1, , 2, 3, 3, 4, 4))) + rel_a <- rel_from_df(con, data.frame(a = c(1:8), b = c(1, 1, 2, 2, 3, 3, 4, 4))) partitions <- list(expr_reference("b")) mod_function <- expr_function("mod", list(expr_reference("a"), expr_constant(2))) zero <- expr_constant(0) @@ -662,7 +662,7 @@ test_that("Window avg with a filter expression and partition works", { test_that("Window lag function works as expected", { # select a, b, lag(a, 1) OVER () order by a - reldf_a <- rel_from_df(con, data.frame(a = c(1:8), b = c(1, 1, , 2, 3, 3, 4, 4))) + rel_a <- rel_from_df(con, data.frame(a = c(1:8), b = c(1, 1, 2, 2, 3, 3, 4, 4))) lag <- expr_function("lag", list(expr_reference("a"))) window_lag <- expr_window(lag, offset_expr = expr_constant(1)) expr_set_alias(window_lag, "lag") @@ -676,7 +676,7 @@ test_that("Window lag function works as expected", { test_that("function name for window is case insensitive", { # select a, b, lag(a, 1) OVER () order by a - reldf_a <- rel_from_df(con, data.frame(a = c(1:8), b = c(1, 1, , 2, 3, 3, 4, 4))) + rel_a <- rel_from_df(con, data.frame(a = c(1:8), b = c(1, 1, 2, 2, 3, 3, 4, 4))) lag <- expr_function("LAG", list(expr_reference("a"))) window_lag <- expr_window(lag, offset_expr = expr_constant(1)) expr_set_alias(window_lag, "lag") @@ -689,7 +689,7 @@ test_that("function name for window is case insensitive", { test_that("Window lead function works as expected", { # select a, b, lag(a, 1) OVER () order by a - reldf_a <- rel_from_df(con, data.frame(a = c(1:8), b = c(1, 1, , 2, 3, 3, 4, 4))) + rel_a <- rel_from_df(con, data.frame(a = c(1:8), b = c(1, 1, 2, 2, 3, 3, 4, 4))) lead <- expr_function("lead", list(expr_reference("a"))) window_lead <- expr_window(lead, offset_expr = expr_constant(1)) expr_set_alias(window_lead, "lead") @@ -702,7 +702,7 @@ test_that("Window lead function works as expected", { test_that("Window function with string aggregate works", { # select j, s, string_agg(s, '|') over (partition by b) from a order by j, s; - reldf_a <- rel_from_df(con, data.frame(r = c(1, , 3, 4), a = c("hello", "Big", "world", "42"), b = c(1, 1, 2, 2))) + rel_a <- rel_from_df(con, data.frame(r = c(1, 2, 3, 4), a = c("hello", "Big", "world", "42"), b = c(1, 1, 2, 2))) str_agg <- expr_function("string_agg", list(expr_reference("a"))) partitions <- list(expr_reference("b")) window_str_cat <- expr_window(str_agg, partitions = partitions) @@ -716,7 +716,7 @@ test_that("Window function with string aggregate works", { test_that("You can perform window functions on row_number", { # select a, b, row_number() OVER () from tmp order by a; - reldf_a <- rel_from_df(con, data.frame(a = c(8:1), b = c(1, 1, , 2, 3, 3, 4, 4))) + rel_a <- rel_from_df(con, data.frame(a = c(8:1), b = c(1, 1, 2, 2, 3, 3, 4, 4))) row_number <- expr_function("row_number", list()) window_function <- expr_window(row_number) expr_set_alias(window_function, "row_number") @@ -732,7 +732,7 @@ test_that("You can perform window functions on row_number", { # in dplyr min_rank = rank test_that("You can perform the window function min_rank", { # select rank() OVER (order by a) from t1 - reldf_a <- rel_from_df(con, data.frame(a = c(1, 1, , 2, 2))) + rel_a <- rel_from_df(con, data.frame(a = c(1, 1, 2, 2, 2))) rank_func <- expr_function("rank", list()) min_rank_window <- expr_window(rank_func, order_bys = list(expr_reference("a"))) expr_set_alias(min_rank_window, "window_result") @@ -744,7 +744,7 @@ test_that("You can perform the window function min_rank", { test_that("You can perform the window function dense_rank", { # select dense_rank() OVER (order by a) from t1; - reldf_a <- rel_from_df(con, data.frame(a = c(1, 1, , 2, 2))) + rel_a <- rel_from_df(con, data.frame(a = c(1, 1, 2, 2, 2))) dense_rank_fun <- expr_function("dense_rank", list()) min_rank_window <- expr_window(dense_rank_fun, order_bys = list(expr_reference("a"))) expr_set_alias(min_rank_window, "window_result") @@ -756,7 +756,7 @@ test_that("You can perform the window function dense_rank", { test_that("You can perform the window function cume_dist", { # select cume_dist() OVER (order by a) from t1; - reldf_a <- rel_from_df(con, data.frame(a = c(1, 1, , 2, 2))) + rel_a <- rel_from_df(con, data.frame(a = c(1, 1, 2, 2, 2))) cume_dist_func <- expr_function("cume_dist", list()) cume_dist_window <- expr_window(cume_dist_func, order_bys = list(expr_reference("a"))) expr_set_alias(cume_dist_window, "cume_dist") @@ -769,7 +769,7 @@ test_that("You can perform the window function cume_dist", { test_that("You can perform the window function percent rank", { # select percent_rank() OVER (order by a) from t1; - reldf_a <- rel_from_df(con, data.frame(a = c(5, 1, 3, , 2))) + rel_a <- rel_from_df(con, data.frame(a = c(5, 1, 3, 2, 2))) percent_rank_func <- expr_function("percent_rank", list()) percent_rank_wind <- expr_window(percent_rank_func, order_bys = list(expr_reference("a"))) expr_set_alias(percent_rank_wind, "percent_rank") @@ -783,7 +783,7 @@ test_that("You can perform the window function percent rank", { # with and without offsets test_that("R semantics for adding NaNs is respected", { dbExecute(con, "CREATE OR REPLACE MACRO eq(a, b) AS a = b") - test_df_a <- reldf_from_df(con, data.frame(a = c(1, ), b = c(3, 4))) + test_df_a <- rel_from_df(con, data.frame(a = c(1, 2), b = c(3, 4))) test_df_b <- rel_from_df(con, data.frame(c = c(NaN, 6), d = c(3, 8))) cond <- list(expr_function("eq", list(expr_reference("b"), expr_reference("d")))) rel_join <- rel_join(test_df_a, test_df_b, cond, "inner") @@ -803,20 +803,20 @@ test_that("R semantics for arithmetics sum function are respected", { test_that("anti joins for eq_na_matches works", { dbExecute(con, 'CREATE OR REPLACE MACRO "___eq_na_matches_na"(a, b) AS ((a IS NULL AND b IS NULL) OR (a = b))') - rel1 <- reldf_from_df(con, data.frame(x = c(1, 1, , 3))) - rel2 <- reldf_from_df(con, data.frame(y = c(, 3, 3, 4))) + rel1 <- rel_from_df(con, data.frame(x = c(1, 1, 2, 3))) + rel2 <- rel_from_df(con, data.frame(y = c(2, 3, 3, 4))) cond <- list(expr_function("___eq_na_matches_na", list(expr_reference("x"), expr_reference("y")))) - out <- reldf_join(rel1, rel, cond, "anti") + out <- rel_join(rel1, rel2, cond, "anti") res <- rel_to_altrep(out) expect_equal(res, data.frame(x = c(1, 1))) }) test_that("semi joins for eq_na_matches works", { dbExecute(con, 'CREATE OR REPLACE MACRO "___eq_na_matches_na"(a, b) AS ((a IS NULL AND b IS NULL) OR (a = b))') - rel1 <- reldf_from_df(con, data.frame(x = c(1, 1, , 2))) - rel2 <- reldf_from_df(con, data.frame(y = c(, 2, 2, 2, 3, 3, 3))) + rel1 <- rel_from_df(con, data.frame(x = c(1, 1, 2, 2))) + rel2 <- rel_from_df(con, data.frame(y = c(2, 2, 2, 2, 3, 3, 3))) cond <- list(expr_function("___eq_na_matches_na", list(expr_reference("x"), expr_reference("y")))) - out <- reldf_join(rel1, rel, cond, "semi") + out <- rel_join(rel1, rel2, cond, "semi") res <- rel_to_altrep(out) expect_equal(res, data.frame(x = c(2, 2))) }) @@ -860,27 +860,27 @@ test_that("rel_explain()", { proj <- rel_project(rel, exprs) expect_snapshot({ - writeLines(reldf_explain_df(proj)[[]]) + writeLines(rel_explain_df(proj)[[2]]) }) expect_snapshot({ - writeLines(reldf_explain_df(proj, "analyze")[[]]) + writeLines(rel_explain_df(proj, "analyze")[[2]]) }) expect_snapshot({ - writeLines(reldf_explain_df(proj, "standard", "json")[[]]) + writeLines(rel_explain_df(proj, "standard", "json")[[2]]) }) expect_snapshot({ - writeLines(reldf_explain_df(proj, "analyze", "json")[[]]) + writeLines(rel_explain_df(proj, "analyze", "json")[[2]]) }) expect_snapshot({ - writeLines(reldf_explain_df(proj, "standard", "html")[[]]) + writeLines(rel_explain_df(proj, "standard", "html")[[2]]) }) expect_snapshot({ - writeLines(reldf_explain_df(proj, "standard", "graphviz")[[]]) + writeLines(rel_explain_df(proj, "standard", "graphviz")[[2]]) }) }) @@ -896,13 +896,13 @@ test_that("rel_to_sql works for row_number", { tmp_expr }) ) - sql <- reldf_to_sql(rel) + sql <- rel_to_sql(rel2) sub_str_sql <- substr(sql, 0, 44) expect_equal(sub_str_sql, "SELECT row_number() OVER () AS ___row_number") }) test_that("rel_from_table_function works", { - rel <- reldf_from_table_function(con, "generate_series", list(1L, 10L, L)) + rel <- rel_from_table_function(con, "generate_series", list(1L, 10L, 2L)) df <- as.data.frame(rel) expect_equal(df$generate_series, c(1, 3, 5, 7, 9)) }) @@ -931,7 +931,7 @@ test_that("we don't crash with evaluation errors", { ) ) - ans <- reldf_to_altrep(rel) + ans <- rel_to_altrep(rel2) # This query is supposed to throw a runtime error. # If this succeeds, find a new query that throws a runtime error. @@ -962,7 +962,7 @@ test_that("we don't crash with evaluation errors", { ) ) - ans <- reldf_to_altrep(rel) + ans <- rel_to_altrep(rel2) # This query is supposed to throw a runtime error. # If this succeeds, find a new query that throws a runtime error. @@ -998,41 +998,41 @@ test_that("tethering", { ) ) - forbid <- reldf_to_altrep(rel, allow_materialization = FALSE) + forbid <- rel_to_altrep(rel2, allow_materialization = FALSE) expect_snapshot(error = TRUE, { nrow(forbid) }) - forbid_nrow <- reldf_to_altrep(rel, n_cells = 0) + forbid_nrow <- rel_to_altrep(rel2, n_cells = 0) expect_snapshot(error = TRUE, { nrow(forbid) }) - five_rows <- reldf_to_altrep(rel, n_rows = 5) + five_rows <- rel_to_altrep(rel2, n_rows = 5) expect_error(nrow(five_rows), NA) - four_rows <- reldf_to_altrep(rel, n_rows = 4) + four_rows <- rel_to_altrep(rel2, n_rows = 4) expect_snapshot(error = TRUE, { nrow(four_rows) }) - ten_cells <- reldf_to_altrep(rel, n_cells = 10) + ten_cells <- rel_to_altrep(rel2, n_cells = 10) expect_error(nrow(ten_cells), NA) - nine_cells <- reldf_to_altrep(rel, n_cells = 9) + nine_cells <- rel_to_altrep(rel2, n_cells = 9) expect_snapshot(error = TRUE, { nrow(nine_cells) }) - ok_both <- reldf_to_altrep(rel, n_rows = 5, n_cells = 10) + ok_both <- rel_to_altrep(rel2, n_rows = 5, n_cells = 10) expect_error(nrow(ok_both), NA) - bad_rows <- reldf_to_altrep(rel, n_rows = 4, n_cells = 10) + bad_rows <- rel_to_altrep(rel2, n_rows = 4, n_cells = 10) expect_snapshot(error = TRUE, { nrow(bad_rows) }) - bad_cells <- reldf_to_altrep(rel, n_rows = 5, n_cells = 9) + bad_cells <- rel_to_altrep(rel2, n_rows = 5, n_cells = 9) expect_snapshot(error = TRUE, { nrow(bad_cells) }) From 83f43fc62946ae7988fe01d8e57aecf8462f00c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Sat, 8 Mar 2025 20:41:55 +0100 Subject: [PATCH 60/69] Add --- src/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ca417c971..cf8db49ce 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -9,6 +9,7 @@ add_library( database.cpp register.cpp relational.cpp + relational2.cpp reltoaltrep.cpp altrepdataframe_relation.cpp scan.cpp From b2335484a3806ba824b7ed307291eb2b397b2050 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Sat, 8 Mar 2025 20:48:13 +0100 Subject: [PATCH 61/69] Adapt --- R/relational2.R | 91 ++++++++++++++++++++++++++----------------------- 1 file changed, 48 insertions(+), 43 deletions(-) diff --git a/R/relational2.R b/R/relational2.R index a4cd14f76..fa07d62c8 100644 --- a/R/relational2.R +++ b/R/relational2.R @@ -5,8 +5,8 @@ #' @noRd #' @examples #' con <- DBI::dbConnect(duckdb()) -#' rel <- rel_from_df(con, mtcars) -#' rel2 <- rel_limit(rel, 10) +#' df <- data.frame(a = 1:5, b = letters[1:5]) +#' rel2 <- reldf_limit(df, con, 3) reldf_limit <- function(df, con, n) { rethrow_rapi_reldf_limit(df, con@conn_ref, n) } @@ -18,8 +18,8 @@ reldf_limit <- function(df, con, n) { #' @noRd #' @examples #' con <- DBI::dbConnect(duckdb()) -#' rel <- rel_from_df(con, mtcars) -#' rel2 <- rel_project(rel, list(expr_reference("cyl"), expr_reference("disp"))) +#' df <- data.frame(a = 1:3, b = letters[1:3], c = LETTERS[1:3]) +#' rel2 <- reldf_project(df, con, list(expr_reference("a"), expr_reference("c"))) reldf_project <- function(df, con, exprs) { rethrow_rapi_reldf_project(df, con@conn_ref, exprs) } @@ -32,8 +32,8 @@ reldf_project <- function(df, con, exprs) { #' @examples #' con <- DBI::dbConnect(duckdb()) #' DBI::dbExecute(con, "CREATE OR REPLACE MACRO gt(a, b) AS a > b") -#' rel <- rel_from_df(con, mtcars) -#' rel2 <- rel_filter(rel, list(expr_function("gt", list(expr_reference("cyl"), expr_constant("6"))))) +#' df <- data.frame(a = 1:5, b = letters[1:5]) +#' rel2 <- reldf_filter(df, con, list(expr_function("gt", list(expr_reference("a"), expr_constant(2))))) reldf_filter <- function(df, con, exprs) { rethrow_rapi_reldf_filter(df, con@conn_ref, exprs) } @@ -46,9 +46,9 @@ reldf_filter <- function(df, con, exprs) { #' @noRd #' @examples #' con <- DBI::dbConnect(duckdb()) -#' rel <- rel_from_df(con, mtcars) -#' aggrs <- list(avg_hp = expr_function("avg", list(expr_reference("hp")))) -#' rel2 <- rel_aggregate(rel, list(expr_reference("cyl")), aggrs) +#' df <- data.frame(group = c("A", "A", "B", "B"), value = c(1, 2, 3, 4)) +#' aggrs <- list(sum_val = expr_function("sum", list(expr_reference("value")))) +#' rel2 <- reldf_aggregate(df, con, list(expr_reference("group")), aggrs) reldf_aggregate <- function(df, con, groups, aggregates) { rethrow_rapi_reldf_aggregate(df, con@conn_ref, groups, aggregates) } @@ -61,8 +61,8 @@ reldf_aggregate <- function(df, con, groups, aggregates) { #' @noRd #' @examples #' con <- DBI::dbConnect(duckdb()) -#' rel <- rel_from_df(con, mtcars) -#' rel2 <- rel_order(rel, list(expr_reference("hp"))) +#' df <- data.frame(a = c(2, 1, 3), b = letters[1:3]) +#' rel2 <- reldf_order(df, con, list(expr_reference("a"))) reldf_order <- function(df, con, orders, ascending = NULL) { if (is.null(ascending)) { ascending <- rep(TRUE, length(orders)) @@ -85,13 +85,13 @@ reldf_order <- function(df, con, orders, ascending = NULL) { #' @examples #' con <- DBI::dbConnect(duckdb()) #' DBI::dbExecute(con, "CREATE OR REPLACE MACRO eq(a, b) AS a = b") -#' left <- rel_from_df(con, mtcars) -#' right <- rel_from_df(con, mtcars) -#' cond <- list(expr_function("eq", list(expr_reference("cyl", left), expr_reference("cyl", right)))) -#' rel2 <- rel_join(left, right, cond, "inner") -#' rel2 <- rel_join(left, right, cond, "right") -#' rel2 <- rel_join(left, right, cond, "left") -#' rel2 <- rel_join(left, right, cond, "outer") +#' left <- data.frame(id = 1:3, val_a = c("a", "b", "c")) +#' right <- data.frame(id = 2:4, val_b = c("x", "y", "z")) +#' cond <- list(expr_function("eq", list(expr_reference("id", left), expr_reference("id", right)))) +#' rel2 <- reldf_join(left, right, con, cond, "inner") +#' rel2 <- reldf_join(left, right, con, cond, "right") +#' rel2 <- reldf_join(left, right, con, cond, "left") +#' rel2 <- reldf_join(left, right, con, cond, "outer") reldf_join <- function( left, right, @@ -117,9 +117,9 @@ reldf_join <- function( #' @noRd #' @examples #' con <- DBI::dbConnect(duckdb()) -#' rel_a <- rel_from_df(con, mtcars) -#' rel_b <- rel_from_df(con, mtcars) -#' rel_union_all(rel_a, rel_b) +#' df_a <- data.frame(a = 1:2, b = c("a", "b")) +#' df_b <- data.frame(a = 3:4, b = c("c", "d")) +#' reldf_union_all(df_a, df_b, con) reldf_union_all <- function(df_a, df_b, con) { rethrow_rapi_reldf_union_all(df_a, df_b, con@conn_ref) } @@ -130,8 +130,8 @@ reldf_union_all <- function(df_a, df_b, con) { #' @noRd #' @examples #' con <- DBI::dbConnect(duckdb()) -#' rel <- rel_from_df(con, mtcars) -#' rel2 <- rel_distinct(rel) +#' df <- data.frame(a = c(1, 1, 2, 2), b = c("a", "a", "b", "c")) +#' rel2 <- reldf_distinct(df, con) reldf_distinct <- function(df, con) { rethrow_rapi_reldf_distinct(df, con@conn_ref) } @@ -142,9 +142,10 @@ reldf_distinct <- function(df, con) { #' @return a new `duckdb_relation` object resulting from the intersection #' @noRd #' @examples -#' rel_a <- rel_from_df(con, mtcars) -#' rel_b <- rel_from_df(con, mtcars) -#' rel_set_intersect_all(rel_a, rel_b) +#' con <- DBI::dbConnect(duckdb()) +#' df_a <- data.frame(a = 1:3, b = letters[1:3]) +#' df_b <- data.frame(a = 2:4, b = letters[2:4]) +#' reldf_set_intersect(df_a, df_b, con) reldf_set_intersect <- function(df_a, df_b, con) { rethrow_rapi_reldf_set_intersect(df_a, df_b, con@conn_ref) } @@ -155,9 +156,10 @@ reldf_set_intersect <- function(df_a, df_b, con) { #' @return a new `duckdb_relation` object resulting from the set difference #' @noRd #' @examples -#' rel_a <- rel_from_df(con, mtcars) -#' rel_b <- rel_from_df(con, mtcars) -#' rel_set_diff(rel_a, rel_b) +#' con <- DBI::dbConnect(duckdb()) +#' df_a <- data.frame(a = 1:3, b = letters[1:3]) +#' df_b <- data.frame(a = 2:4, b = letters[2:4]) +#' reldf_set_diff(df_a, df_b, con) reldf_set_diff <- function(df_a, df_b, con) { rethrow_rapi_reldf_set_diff(df_a, df_b, con@conn_ref) } @@ -168,9 +170,10 @@ reldf_set_diff <- function(df_a, df_b, con) { #' @return a new `duckdb_relation` object resulting from the symmetric difference of rel_a and rel_b #' @noRd #' @examples -#' rel_a <- rel_from_df(con, mtcars) -#' rel_b <- rel_from_df(con, mtcars) -#' rel_set_symdiff(rel_a, rel_b) +#' con <- DBI::dbConnect(duckdb()) +#' df_a <- data.frame(a = 1:3, b = letters[1:3]) +#' df_b <- data.frame(a = 2:4, b = letters[2:4]) +#' reldf_set_symdiff(df_a, df_b, con) reldf_set_symdiff <- function(df_a, df_b, con) { rethrow_rapi_reldf_set_symdiff(df_a, df_b, con@conn_ref) } @@ -180,8 +183,8 @@ reldf_set_symdiff <- function(df_a, df_b, con) { #' @noRd #' @examples #' con <- DBI::dbConnect(duckdb()) -#' rel <- rel_from_df(con, mtcars) -#' rel_explain(rel) +#' df <- data.frame(a = 1:3, b = letters[1:3]) +#' reldf_explain(df, con) reldf_explain <- function(df, con) { # Legacy cat(rethrow_rapi_reldf_explain(df, con@conn_ref, "EXPLAIN_STANDARD", "DEFAULT")[[2]][[1]]) @@ -193,8 +196,8 @@ reldf_explain <- function(df, con) { #' @noRd #' @examples #' con <- DBI::dbConnect(duckdb()) -#' rel <- rel_from_df(con, mtcars) -#' rel_alias(rel) +#' df <- data.frame(a = 1:3, b = letters[1:3]) +#' reldf_alias(df, con) reldf_alias <- function(df, con) { rethrow_rapi_reldf_alias(df, con@conn_ref) } @@ -205,8 +208,8 @@ reldf_alias <- function(df, con) { #' @noRd #' @examples #' con <- DBI::dbConnect(duckdb()) -#' rel <- rel_from_df(con, mtcars) -#' rel_set_alias(rel, "my_new_alias") +#' df <- data.frame(a = 1:3, b = letters[1:3]) +#' reldf_set_alias(df, con, "my_new_alias") reldf_set_alias <- function(df, con, alias) { rethrow_rapi_reldf_set_alias(df, con@conn_ref, alias) } @@ -217,8 +220,9 @@ reldf_set_alias <- function(df, con, alias) { #' @noRd #' @examples #' con <- DBI::dbConnect(duckdb()) -#' DBI::dbWriteTable(con, "mtcars", mtcars) -#' rel <- rel_from_sql(con, "SELECT * FROM mtcars") +#' df <- data.frame(a = 1:3, b = letters[1:3]) +#' DBI::dbWriteTable(con, "small_table", df) +#' reldf_from_sql(con, "SELECT * FROM small_table") reldf_from_sql <- function(con, sql) { rethrow_rapi_reldf_from_sql(con@conn_ref, sql) } @@ -229,8 +233,9 @@ reldf_from_sql <- function(con, sql) { #' @noRd #' @examples #' con <- DBI::dbConnect(duckdb()) -#' DBI::dbWriteTable(con, "mtcars", mtcars) -#' rel <- rel_from_table(con, "mtcars") +#' df <- data.frame(a = 1:3, b = letters[1:3]) +#' DBI::dbWriteTable(con, "small_table", df) +#' reldf_from_table(con, "small_table") reldf_from_table <- function(con, table_name, schema_name = "MAIN") { rethrow_rapi_reldf_from_table(con@conn_ref, schema_name, table_name) } @@ -243,7 +248,7 @@ reldf_from_table <- function(con, table_name, schema_name = "MAIN") { #' @noRd #' @examples #' con <- DBI::dbConnect(duckdb()) -#' rel <- rel_from_table_function(con, 'generate_series', list(10L)) +#' reldf_from_table_function(con, 'generate_series', list(10L)) reldf_from_table_function <- function(con, function_name, positional_parameters = list(), named_parameters = list()) { rethrow_rapi_reldf_from_table_function(con@conn_ref, function_name, positional_parameters, named_parameters) } From 32de0e53f3809db8ef17318cfb75545b2134dfed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Sun, 9 Mar 2025 15:14:22 +0100 Subject: [PATCH 62/69] Goof --- src/reltoaltrep.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/reltoaltrep.cpp b/src/reltoaltrep.cpp index c2d4a8cff..73c152fa7 100644 --- a/src/reltoaltrep.cpp +++ b/src/reltoaltrep.cpp @@ -550,7 +550,7 @@ SEXP rapi_reldf_to_altrep(duckdb::rel_extptr_t rel, duckdb::conn_eptr_t con, boo auto res = R_altrep_data2(row_names); if (res == R_NilValue) { if (strict) { - cpp11::stop("rapi_reldf_from_altrep_df: NULL in data?"); + cpp11::stop("rapi_rel_from_altrep_df: NULL in data2?"); } else { return R_NilValue; } From 80d77dea0c56453ac22bf269b4b67966cd17b064 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Sun, 9 Mar 2025 23:01:57 +0100 Subject: [PATCH 63/69] Avoid auto_init = false for existing code --- src/relational.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/relational.cpp b/src/relational.cpp index d484a6589..93594642b 100644 --- a/src/relational.cpp +++ b/src/relational.cpp @@ -140,7 +140,7 @@ using namespace cpp11; auto alias = StringUtil::Format("dataframe_%d_%d", (uintptr_t)(SEXP)df, (int32_t)(NumericLimits::Maximum() * unif_rand())); auto rel = - con->conn->TableFunction("r_dataframe_scan", {Value::POINTER((uintptr_t)(SEXP)df)}, other_params, false)->Alias(alias); + con->conn->TableFunction("r_dataframe_scan", {Value::POINTER((uintptr_t)(SEXP)df)}, other_params)->Alias(alias); cpp11::writable::list prot = {df}; From c92d876974e9f7148d415cc7178f38a2e7a1bacd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Mon, 10 Mar 2025 04:53:30 +0100 Subject: [PATCH 64/69] Fix Windows --- src/Makevars.in | 2 +- src/Makevars.win | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Makevars.in b/src/Makevars.in index e6959f8c7..fb1b4d02e 100644 --- a/src/Makevars.in +++ b/src/Makevars.in @@ -17,5 +17,5 @@ include Makevars.duckdb CXX_STD = CXX17 PKG_CPPFLAGS = -Iinclude -I../inst/include -DDUCKDB_DISABLE_PRINT -DDUCKDB_R_BUILD -DBROTLI_ENCODER_CLEANUP_ON_OOM {{ INCLUDES }} -OBJECTS=rfuns.o database.o connection.o statement.o register.o relational.o scan.o signal.o transform.o utils.o reltoaltrep.o types.o cpp11.o $(SOURCES) +OBJECTS=rfuns.o database.o connection.o statement.o register.o relational.o relational2.o scan.o signal.o transform.o utils.o reltoaltrep.o altrepdataframe_relation.o types.o cpp11.o $(SOURCES) PKG_LIBS={{ LINK_FLAGS }} diff --git a/src/Makevars.win b/src/Makevars.win index 3b1d2adc9..78bb4f8da 100644 --- a/src/Makevars.win +++ b/src/Makevars.win @@ -17,5 +17,5 @@ include Makevars.duckdb CXX_STD = CXX17 PKG_CPPFLAGS = -Iinclude -I../inst/include -DDUCKDB_DISABLE_PRINT -DDUCKDB_R_BUILD -DBROTLI_ENCODER_CLEANUP_ON_OOM -Iduckdb/src/include -Iduckdb/third_party/concurrentqueue -Iduckdb/third_party/fast_float -Iduckdb/third_party/fastpforlib -Iduckdb/third_party/fmt/include -Iduckdb/third_party/fsst -Iduckdb/third_party/httplib -Iduckdb/third_party/hyperloglog -Iduckdb/third_party/jaro_winkler -Iduckdb/third_party/jaro_winkler/details -Iduckdb/third_party/libpg_query -Iduckdb/third_party/libpg_query/include -Iduckdb/third_party/lz4 -Iduckdb/third_party/brotli/include -Iduckdb/third_party/brotli/common -Iduckdb/third_party/brotli/dec -Iduckdb/third_party/brotli/enc -Iduckdb/third_party/mbedtls -Iduckdb/third_party/mbedtls/include -Iduckdb/third_party/mbedtls/library -Iduckdb/third_party/miniz -Iduckdb/third_party/pcg -Iduckdb/third_party/re2 -Iduckdb/third_party/skiplist -Iduckdb/third_party/tdigest -Iduckdb/third_party/utf8proc -Iduckdb/third_party/utf8proc/include -Iduckdb/third_party/yyjson/include -Iduckdb/third_party/zstd/include -Iduckdb/extension/parquet/include -Iduckdb/third_party/parquet -Iduckdb/third_party/thrift -Iduckdb/third_party/lz4 -Iduckdb/third_party/brotli/include -Iduckdb/third_party/brotli/common -Iduckdb/third_party/brotli/dec -Iduckdb/third_party/brotli/enc -Iduckdb/third_party/snappy -Iduckdb/third_party/mbedtls -Iduckdb/third_party/mbedtls/include -Iduckdb/third_party/zstd/include -Iduckdb/extension/core_functions/include -I../inst/include -Iduckdb -DDUCKDB_EXTENSION_PARQUET_LINKED -DDUCKDB_BUILD_LIBRARY -DDUCKDB_EXTENSION_CORE_FUNCTIONS_LINKED -DDUCKDB_BUILD_LIBRARY -DDUCKDB_PLATFORM_RTOOLS=1 -OBJECTS=rfuns.o database.o connection.o statement.o register.o relational.o scan.o signal.o transform.o utils.o reltoaltrep.o types.o cpp11.o $(SOURCES) +OBJECTS=rfuns.o database.o connection.o statement.o register.o relational.o relational2.o scan.o signal.o transform.o utils.o reltoaltrep.o altrepdataframe_relation.o types.o cpp11.o $(SOURCES) PKG_LIBS=-lws2_32 -L. -lrstrtmgr From 4d659af8a312e3f773c2e0f33011c8da104f51fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Mon, 10 Mar 2025 05:44:43 +0100 Subject: [PATCH 65/69] Keep n_rows and n_cells, avoid using ALTREP data2 --- src/include/reltoaltrep.hpp | 7 ++-- src/relational2.cpp | 32 +++++++++---------- src/reltoaltrep.cpp | 64 ++++++++++++++++++++++--------------- 3 files changed, 58 insertions(+), 45 deletions(-) diff --git a/src/include/reltoaltrep.hpp b/src/include/reltoaltrep.hpp index f95fa3825..2df0e0636 100644 --- a/src/include/reltoaltrep.hpp +++ b/src/include/reltoaltrep.hpp @@ -10,7 +10,7 @@ struct AltrepRelationWrapper { static AltrepRelationWrapper *Get(SEXP x); - AltrepRelationWrapper(rel_extptr_t rel_, bool allow_materialization_, size_t n_rows_, size_t n_cells_, SEXP df_); + AltrepRelationWrapper(rel_extptr_t rel_, size_t n_rows_, size_t n_cells_, SEXP df_); bool HasQueryResult() const; @@ -18,7 +18,6 @@ struct AltrepRelationWrapper { void Materialize(); - const bool allow_materialization; const size_t n_rows; const size_t n_cells; @@ -60,8 +59,10 @@ struct RelToAltrep { SEXP rapi_rel_from_altrep_df(SEXP df, bool strict, bool allow_materialized); +std::pair rapi_rel_wrapper_args_from_altrep_df(SEXP df); + SEXP rapi_rel_from_any_df(duckdb::conn_eptr_t con, SEXP df, bool allow_materialized); -SEXP rapi_reldf_to_altrep(duckdb::rel_extptr_t rel, duckdb::conn_eptr_t con, bool allow_materialization); +SEXP rapi_reldf_to_altrep(duckdb::rel_extptr_t rel, duckdb::conn_eptr_t con, cpp11::list template_); SEXP result_to_df(duckdb::unique_ptr res); diff --git a/src/relational2.cpp b/src/relational2.cpp index 181c1c316..2cef9aa2e 100644 --- a/src/relational2.cpp +++ b/src/relational2.cpp @@ -48,7 +48,7 @@ using namespace cpp11; auto rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); cpp11::writable::list prot = {rel}; - return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, rel->rel->Alias(alias)), con, true); + return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, rel->rel->Alias(alias)), con, df); } // DuckDB Relations: operators @@ -73,7 +73,7 @@ using namespace cpp11; cpp11::writable::list prot = {rel}; - return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(filter)), con, true); + return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(filter)), con, df); } [[cpp11::register]] SEXP rapi_reldf_project(data_frame df, duckdb::conn_eptr_t con, list exprs) { @@ -96,7 +96,7 @@ using namespace cpp11; cpp11::writable::list prot = {rel}; - return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(projection)), con, true); + return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(projection)), con, df); } [[cpp11::register]] SEXP rapi_reldf_aggregate(data_frame df, duckdb::conn_eptr_t con, list groups, list aggregates) { @@ -127,7 +127,7 @@ using namespace cpp11; cpp11::writable::list prot = {rel}; - return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(aggregate)), con, true); + return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(aggregate)), con, df); } [[cpp11::register]] SEXP rapi_reldf_order(data_frame df, duckdb::conn_eptr_t con, list orders, r_vector ascending) { @@ -148,7 +148,7 @@ using namespace cpp11; cpp11::writable::list prot = {rel}; - return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(order)), con, true); + return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(order)), con, df); } [[cpp11::register]] SEXP rapi_reldf_join(data_frame left, data_frame right, duckdb::conn_eptr_t con, list conds, @@ -189,7 +189,7 @@ using namespace cpp11; ref_type = JoinRefType::CROSS; } auto res = make_shared_ptr(rel_left->rel, rel_right->rel, ref_type); - auto df = rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(res)), con, true); + auto df = rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(res)), con, left); // if the user described filters, apply them on top of the cross product relation if (conds.size() > 0) { return rapi_reldf_filter(df, con, conds); @@ -208,7 +208,7 @@ using namespace cpp11; } auto res = make_shared_ptr(rel_left->rel, rel_right->rel, std::move(cond), join_type, ref_type); - return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(res)), con, true); + return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(res)), con, left); } [[cpp11::register]] SEXP rapi_reldf_union_all(data_frame left, data_frame right, duckdb::conn_eptr_t con) { @@ -220,7 +220,7 @@ using namespace cpp11; auto setop = make_shared_ptr(rel_left->rel, rel_right->rel, SetOperationType::UNION); setop->setop_all = true; - return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(setop)), con, true); + return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(setop)), con, left); } [[cpp11::register]] SEXP rapi_reldf_limit(data_frame df, duckdb::conn_eptr_t con, int64_t n) { @@ -228,7 +228,7 @@ using namespace cpp11; cpp11::writable::list prot = {rel}; - return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, make_shared_ptr(rel->rel, n, 0)), con, true); + return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, make_shared_ptr(rel->rel, n, 0)), con, df); } [[cpp11::register]] SEXP rapi_reldf_distinct(data_frame df, duckdb::conn_eptr_t con) { @@ -236,7 +236,7 @@ using namespace cpp11; cpp11::writable::list prot = {rel}; - return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, make_shared_ptr(rel->rel)), con, true); + return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, make_shared_ptr(rel->rel)), con, df); } [[cpp11::register]] SEXP rapi_reldf_set_intersect(data_frame left, data_frame right, duckdb::conn_eptr_t con) { @@ -247,7 +247,7 @@ using namespace cpp11; cpp11::writable::list prot = {rel_left, rel_right}; - return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(res)), con, true); + return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(res)), con, left); } [[cpp11::register]] SEXP rapi_reldf_set_diff(data_frame left, data_frame right, duckdb::conn_eptr_t con) { @@ -258,7 +258,7 @@ using namespace cpp11; cpp11::writable::list prot = {rel_left, rel_right}; - return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(res)), con, true); + return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(res)), con, left); } [[cpp11::register]] SEXP rapi_reldf_set_symdiff(data_frame left, data_frame right, duckdb::conn_eptr_t con) { @@ -273,7 +273,7 @@ using namespace cpp11; cpp11::writable::list prot = {rel_left, rel_right}; - return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(symdiff)), con, true); + return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(symdiff)), con, left); } // DuckDB Relations: conversion @@ -284,7 +284,7 @@ using namespace cpp11; } auto rel = con->conn->RelationFromQuery(sql); cpp11::writable::list prot = {}; - return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(rel)), con, true); + return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(rel)), con, R_NilValue); } [[cpp11::register]] SEXP rapi_reldf_from_table(duckdb::conn_eptr_t con, const std::string schema_name, @@ -294,7 +294,7 @@ using namespace cpp11; } auto rel = con->conn->Table(schema_name, table_name); cpp11::writable::list prot = {}; - return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(rel)), con, true); + return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(rel)), con, R_NilValue); } [[cpp11::register]] SEXP rapi_reldf_from_table_function(duckdb::conn_eptr_t con, const std::string function_name, @@ -327,7 +327,7 @@ using namespace cpp11; } auto rel = con->conn->TableFunction(function_name, std::move(positional_parameters), std::move(named_parameters)); - return rapi_reldf_to_altrep(make_external("duckdb_relation", std::move(rel)), con, true); + return rapi_reldf_to_altrep(make_external("duckdb_relation", std::move(rel)), con, R_NilValue); } [[cpp11::register]] SEXP rapi_reldf_explain(data_frame df, duckdb::conn_eptr_t con, std::string type, std::string format) { diff --git a/src/reltoaltrep.cpp b/src/reltoaltrep.cpp index 5bea19a81..39e78c226 100644 --- a/src/reltoaltrep.cpp +++ b/src/reltoaltrep.cpp @@ -103,9 +103,9 @@ AltrepRelationWrapper *AltrepRelationWrapper::Get(SEXP x) { return GetFromExternalPtr(x); } -AltrepRelationWrapper::AltrepRelationWrapper(rel_extptr_t rel_, bool allow_materialization_, size_t n_rows_, +AltrepRelationWrapper::AltrepRelationWrapper(rel_extptr_t rel_, size_t n_rows_, size_t n_cells_, SEXP df_) - : allow_materialization(allow_materialization_), n_rows(n_rows_), n_cells(n_cells_), rel_eptr(rel_), + : n_rows(n_rows_), n_cells(n_cells_), rel_eptr(rel_), rel(rel_->rel), df(df_) { } @@ -119,7 +119,7 @@ MaterializedQueryResult *AltrepRelationWrapper::GetQueryResult() { } if (!mat_result) { - if (!allow_materialization || n_cells == 0) { + if (n_cells == 0) { cpp11::stop("Materialization is disabled, use collect() or as_tibble() to materialize."); } @@ -423,8 +423,7 @@ size_t DoubleToSize(double d) { // convert to SEXP (void)(SEXP)data_frame; - const auto allow_materialization = true; - auto relation_wrapper = make_shared_ptr(rel, allow_materialization, DoubleToSize(n_rows), + auto relation_wrapper = make_shared_ptr(rel, DoubleToSize(n_rows), DoubleToSize(n_cells), data_frame); for (size_t col_idx = 0; col_idx < ncols; col_idx++) { @@ -432,7 +431,7 @@ size_t DoubleToSize(double d) { cpp11::external_pointer ptr(new AltrepVectorWrapper(relation_wrapper, col_idx)); R_SetExternalPtrTag(ptr, RStrings::get().duckdb_vector_sym); - cpp11::sexp vector_sexp = R_new_altrep(LogicalTypeToAltrepType(column_type), ptr, rel); + cpp11::sexp vector_sexp = R_new_altrep(LogicalTypeToAltrepType(column_type), ptr, R_NilValue); duckdb_r_decorate(column_type, vector_sexp, false); data_frame[col_idx] = vector_sexp; @@ -448,7 +447,7 @@ size_t DoubleToSize(double d) { // Row names cpp11::external_pointer ptr(new AltrepRownamesWrapper(relation_wrapper)); R_SetExternalPtrTag(ptr, RStrings::get().duckdb_row_names_sym); - cpp11::sexp row_names_sexp = R_new_altrep(RelToAltrep::rownames_class, ptr, rel); + cpp11::sexp row_names_sexp = R_new_altrep(RelToAltrep::rownames_class, ptr, R_NilValue); install_new_attrib(data_frame, R_RowNamesSymbol, row_names_sexp); // Class @@ -458,7 +457,7 @@ size_t DoubleToSize(double d) { } -SEXP rapi_reldf_to_altrep(duckdb::rel_extptr_t rel, duckdb::conn_eptr_t con, bool allow_materialization) { +SEXP rapi_reldf_to_altrep(duckdb::rel_extptr_t rel, duckdb::conn_eptr_t con, cpp11::list template_) { D_ASSERT(rel && rel->rel); auto drel = rel->rel; auto ncols = drel->Columns().size(); @@ -466,7 +465,9 @@ SEXP rapi_reldf_to_altrep(duckdb::rel_extptr_t rel, duckdb::conn_eptr_t con, boo cpp11::writable::list data_frame; data_frame.resize(ncols); - auto relation_wrapper = make_shared_ptr(rel, allow_materialization, MAX_SIZE_T, MAX_SIZE_T, data_frame); + auto template_wrapper_args = rapi_rel_wrapper_args_from_altrep_df(template_); + + auto relation_wrapper = make_shared_ptr(rel, template_wrapper_args.first, template_wrapper_args.second, data_frame); // convert to SEXP (void)(SEXP)data_frame; @@ -476,7 +477,7 @@ SEXP rapi_reldf_to_altrep(duckdb::rel_extptr_t rel, duckdb::conn_eptr_t con, boo cpp11::external_pointer ptr(new AltrepVectorWrapper(relation_wrapper, col_idx)); R_SetExternalPtrTag(ptr, RStrings::get().duckdb_vector_sym); - cpp11::sexp vector_sexp = R_new_altrep(LogicalTypeToAltrepType(column_type), ptr, rel); + cpp11::sexp vector_sexp = R_new_altrep(LogicalTypeToAltrepType(column_type), ptr, R_NilValue); duckdb_r_decorate(column_type, vector_sexp, false); data_frame[col_idx] = vector_sexp; @@ -492,8 +493,7 @@ SEXP rapi_reldf_to_altrep(duckdb::rel_extptr_t rel, duckdb::conn_eptr_t con, boo // Row names cpp11::external_pointer ptr(new AltrepRownamesWrapper(relation_wrapper)); R_SetExternalPtrTag(ptr, RStrings::get().duckdb_row_names_sym); - cpp11::sexp row_names_sexp = R_new_altrep(RelToAltrep::rownames_class, ptr, make_external("duckdb_relation", - make_shared_ptr(rel->rel, data_frame, con, relation_wrapper))); + cpp11::sexp row_names_sexp = R_new_altrep(RelToAltrep::rownames_class, ptr, R_NilValue); install_new_attrib(data_frame, R_RowNamesSymbol, row_names_sexp); // Class @@ -502,12 +502,12 @@ SEXP rapi_reldf_to_altrep(duckdb::rel_extptr_t rel, duckdb::conn_eptr_t con, boo return data_frame; } -[[cpp11::register]] SEXP rapi_rel_from_altrep_df(SEXP df, bool strict, bool allow_materialized) { +shared_ptr rapi_rel_wrapper_from_altrep_df(SEXP df, bool strict, bool allow_materialized) { if (!Rf_inherits(df, "data.frame")) { if (strict) { cpp11::stop("rapi_rel_from_altrep_df: Not a data.frame"); } else { - return R_NilValue; + return nullptr; } } @@ -516,7 +516,7 @@ SEXP rapi_reldf_to_altrep(duckdb::rel_extptr_t rel, duckdb::conn_eptr_t con, boo if (strict) { cpp11::stop("rapi_rel_from_altrep_df: Not a 'special' data.frame, row names are not ALTREP"); } else { - return R_NilValue; + return nullptr; } } @@ -525,7 +525,7 @@ SEXP rapi_reldf_to_altrep(duckdb::rel_extptr_t rel, duckdb::conn_eptr_t con, boo if (strict) { cpp11::stop("rapi_rel_from_altrep_df: Not our 'special' data.frame, data1 is not external pointer"); } else { - return R_NilValue; + return nullptr; } } @@ -534,7 +534,7 @@ SEXP rapi_reldf_to_altrep(duckdb::rel_extptr_t rel, duckdb::conn_eptr_t con, boo if (strict) { cpp11::stop("rapi_rel_from_altrep_df: Not our 'special' data.frame, tag missing"); } else { - return R_NilValue; + return nullptr; } } @@ -543,20 +543,32 @@ SEXP rapi_reldf_to_altrep(duckdb::rel_extptr_t rel, duckdb::conn_eptr_t con, boo if (wrapper->rel->mat_result.get()) { // We return NULL here even for strict = true // because this is expected from df_is_materialized() - return R_NilValue; + return nullptr; } } - auto res = R_altrep_data2(row_names); - if (res == R_NilValue) { - if (strict) { - cpp11::stop("rapi_rel_from_altrep_df: NULL in data2?"); - } else { - return R_NilValue; - } + return wrapper->rel; +} + +[[cpp11::register]] SEXP rapi_rel_from_altrep_df(SEXP df, bool strict, bool allow_materialized) { + auto wrapper = rapi_rel_wrapper_from_altrep_df(df, strict, allow_materialized); + if (!wrapper) { + return R_NilValue; + } + return wrapper->rel_eptr; +} + +std::pair rapi_rel_wrapper_args_from_altrep_df(SEXP df) { + if (Rf_isNull(df)) { + return std::make_pair(MAX_SIZE_T, MAX_SIZE_T); + } + + auto wrapper = rapi_rel_wrapper_from_altrep_df(df, false, true); + if (!wrapper) { + return std::make_pair(MAX_SIZE_T, MAX_SIZE_T); } - return res; + return std::make_pair(wrapper->n_rows, wrapper->n_cells); } SEXP result_to_df(duckdb::unique_ptr res) { From ce331ba33fca84a70c9606ec418e908191984588 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Mon, 10 Mar 2025 07:56:07 +0100 Subject: [PATCH 66/69] Reorder --- src/altrepdataframe_relation.cpp | 2 +- src/include/altrepdataframe_relation.hpp | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/altrepdataframe_relation.cpp b/src/altrepdataframe_relation.cpp index 7009c44fb..4d5035950 100644 --- a/src/altrepdataframe_relation.cpp +++ b/src/altrepdataframe_relation.cpp @@ -6,9 +6,9 @@ namespace duckdb { AltrepDataFrameRelation::AltrepDataFrameRelation(duckdb::shared_ptr p, cpp11::sexp df, duckdb::conn_eptr_t con, duckdb::shared_ptr altrep) : Relation(p->context, RelationType::EXTENSION_RELATION) - , altrep(std::move(altrep)) , dataframe(df) , connection(std::move(con)) + , altrep(std::move(altrep)) , parent(std::move(p)) { TryBindRelation(columns); } diff --git a/src/include/altrepdataframe_relation.hpp b/src/include/altrepdataframe_relation.hpp index eb272fc61..6454d1b6e 100644 --- a/src/include/altrepdataframe_relation.hpp +++ b/src/include/altrepdataframe_relation.hpp @@ -9,12 +9,14 @@ class AltrepDataFrameRelation final : public Relation { public: AltrepDataFrameRelation(duckdb::shared_ptr p, cpp11::sexp df, duckdb::conn_eptr_t con, duckdb::shared_ptr altrep); - shared_ptr table_function_relation; cpp11::sexp dataframe; duckdb::conn_eptr_t connection; duckdb::shared_ptr altrep; duckdb::shared_ptr parent; + + shared_ptr table_function_relation; vector columns; + public: unique_ptr GetQueryNode() override; From 8b5a73d4bea92a33418ffba524ba2c4f92d817f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Mon, 10 Mar 2025 11:47:08 +0100 Subject: [PATCH 67/69] Format --- src/altrepdataframe_relation.cpp | 24 ++++---- src/include/altrepdataframe_relation.hpp | 12 ++-- src/include/reltoaltrep.hpp | 1 - src/relational.cpp | 23 +++----- src/relational2.cpp | 72 ++++++++++++++++-------- src/reltoaltrep.cpp | 16 +++--- 6 files changed, 83 insertions(+), 65 deletions(-) diff --git a/src/altrepdataframe_relation.cpp b/src/altrepdataframe_relation.cpp index 4d5035950..a37fb87c3 100644 --- a/src/altrepdataframe_relation.cpp +++ b/src/altrepdataframe_relation.cpp @@ -4,12 +4,11 @@ namespace duckdb { -AltrepDataFrameRelation::AltrepDataFrameRelation(duckdb::shared_ptr p, cpp11::sexp df, duckdb::conn_eptr_t con, duckdb::shared_ptr altrep) - : Relation(p->context, RelationType::EXTENSION_RELATION) - , dataframe(df) - , connection(std::move(con)) - , altrep(std::move(altrep)) - , parent(std::move(p)) { +AltrepDataFrameRelation::AltrepDataFrameRelation(duckdb::shared_ptr p, cpp11::sexp df, + duckdb::conn_eptr_t con, + duckdb::shared_ptr altrep) + : Relation(p->context, RelationType::EXTENSION_RELATION), dataframe(df), connection(std::move(con)), + altrep(std::move(altrep)), parent(std::move(p)) { TryBindRelation(columns); } @@ -29,7 +28,7 @@ unique_ptr AltrepDataFrameRelation::GetQueryNode() { return GetParent().GetQueryNode(); } -Relation& AltrepDataFrameRelation::GetParent() { +Relation &AltrepDataFrameRelation::GetParent() { if (altrep->HasQueryResult()) { // here context mutex locked return GetTableRelation(); @@ -43,13 +42,16 @@ void AltrepDataFrameRelation::BuildTableRelation() { named_parameter_map_t other_params; other_params["experimental"] = Value::BOOLEAN(false); auto alias = StringUtil::Format("dataframe_%d_%d", (uintptr_t)(SEXP)dataframe, - (int32_t)(NumericLimits::Maximum() * unif_rand())); + (int32_t)(NumericLimits::Maximum() * unif_rand())); - table_function_relation = connection->conn->TableFunction("r_dataframe_scan", {Value::POINTER((uintptr_t)(SEXP)dataframe)}, other_params, false)->Alias(alias); + table_function_relation = + connection->conn + ->TableFunction("r_dataframe_scan", {Value::POINTER((uintptr_t)(SEXP)dataframe)}, other_params, false) + ->Alias(alias); } } -Relation& AltrepDataFrameRelation::GetTableRelation() { +Relation &AltrepDataFrameRelation::GetTableRelation() { if (!table_function_relation) { BuildTableRelation(); } @@ -57,4 +59,4 @@ Relation& AltrepDataFrameRelation::GetTableRelation() { return *table_function_relation; } -} +} // namespace duckdb diff --git a/src/include/altrepdataframe_relation.hpp b/src/include/altrepdataframe_relation.hpp index 6454d1b6e..ee900bc6a 100644 --- a/src/include/altrepdataframe_relation.hpp +++ b/src/include/altrepdataframe_relation.hpp @@ -7,7 +7,8 @@ namespace duckdb { class AltrepDataFrameRelation final : public Relation { public: - AltrepDataFrameRelation(duckdb::shared_ptr p, cpp11::sexp df, duckdb::conn_eptr_t con, duckdb::shared_ptr altrep); + AltrepDataFrameRelation(duckdb::shared_ptr p, cpp11::sexp df, duckdb::conn_eptr_t con, + duckdb::shared_ptr altrep); cpp11::sexp dataframe; duckdb::conn_eptr_t connection; @@ -27,18 +28,19 @@ class AltrepDataFrameRelation final : public Relation { void BuildTableRelation(); private: - Relation& GetTableRelation(); + Relation &GetTableRelation(); - Relation& GetParent(); + Relation &GetParent(); }; class RebuildRelationException : public std::runtime_error { public: - RebuildRelationException(AltrepDataFrameRelation* target_) : std::runtime_error("RebuildRelationException"), target(target_) { + RebuildRelationException(AltrepDataFrameRelation *target_) + : std::runtime_error("RebuildRelationException"), target(target_) { } public: - AltrepDataFrameRelation* target; + AltrepDataFrameRelation *target; }; } // namespace duckdb diff --git a/src/include/reltoaltrep.hpp b/src/include/reltoaltrep.hpp index 2df0e0636..606c88c3a 100644 --- a/src/include/reltoaltrep.hpp +++ b/src/include/reltoaltrep.hpp @@ -9,7 +9,6 @@ namespace duckdb { struct AltrepRelationWrapper { static AltrepRelationWrapper *Get(SEXP x); - AltrepRelationWrapper(rel_extptr_t rel_, size_t n_rows_, size_t n_cells_, SEXP df_); bool HasQueryResult() const; diff --git a/src/relational.cpp b/src/relational.cpp index 93594642b..a9e526e1a 100644 --- a/src/relational.cpp +++ b/src/relational.cpp @@ -56,16 +56,12 @@ using namespace cpp11; [[cpp11::register]] SEXP rapi_expr_comparison(std::string cmp_op, list exprs) { ExpressionType expr_type = OperatorToExpressionType(cmp_op); - if (expr_type ==ExpressionType::INVALID) { + if (expr_type == ExpressionType::INVALID) { stop("expr_comparison: Invalid comparison operator"); } - return make_external( - "duckdb_expr", - expr_type, - expr_extptr_t(exprs[0])->Copy(), - expr_extptr_t(exprs[1])->Copy() - ); + return make_external("duckdb_expr", expr_type, expr_extptr_t(exprs[0])->Copy(), + expr_extptr_t(exprs[1])->Copy()); } [[cpp11::register]] SEXP rapi_expr_function(std::string name, list args, list order_bys, list filter_bys) { @@ -119,7 +115,7 @@ using namespace cpp11; return expr->ToString(); } - +// // DuckDB Relations: low-level conversion [[cpp11::register]] SEXP rapi_get_null_SEXP_ptr() { @@ -172,7 +168,7 @@ SEXP rapi_rel_from_any_df(duckdb::conn_eptr_t con, SEXP df, bool allow_materiali return result_to_df(std::move(res)); } - +// // DuckDB Relations: questioning [[cpp11::register]] SEXP rapi_rel_sql(duckdb::rel_extptr_t rel, std::string sql) { @@ -183,7 +179,7 @@ SEXP rapi_rel_from_any_df(duckdb::conn_eptr_t con, SEXP df, bool allow_materiali return result_to_df(std::move(res)); } - +// // DuckDB Relations: names [[cpp11::register]] SEXP rapi_rel_names(duckdb::rel_extptr_t rel) { @@ -204,7 +200,7 @@ SEXP rapi_rel_from_any_df(duckdb::conn_eptr_t con, SEXP df, bool allow_materiali return make_external_prot("duckdb_relation", prot, rel->rel->Alias(alias)); } - +// // DuckDB Relations: operators [[cpp11::register]] SEXP rapi_rel_filter(duckdb::rel_extptr_t rel, list exprs) { @@ -298,7 +294,6 @@ SEXP rapi_rel_from_any_df(duckdb::conn_eptr_t con, SEXP df, bool allow_materiali return make_external_prot("duckdb_relation", prot, res); } - static WindowBoundary StringToWindowBoundary(string &window_boundary) { if (window_boundary == "unbounded_preceding") { return WindowBoundary::UNBOUNDED_PRECEDING; @@ -481,7 +476,6 @@ bool constant_expression_is_not_null(duckdb::expr_extptr_t expr) { return make_external_prot("duckdb_relation", prot, symdiff); } - // DuckDB Relations: conversion [[cpp11::register]] SEXP rapi_rel_from_sql(duckdb::conn_eptr_t con, const std::string sql) { @@ -563,7 +557,8 @@ bool constant_expression_is_not_null(duckdb::expr_extptr_t expr) { rel->rel->WriteCSV(file_name, ListToVectorOfValue(options_sexps)); } -[[cpp11::register]] void rapi_rel_to_table(duckdb::rel_extptr_t rel, std::string schema_name, std::string table_name, bool temporary) { +[[cpp11::register]] void rapi_rel_to_table(duckdb::rel_extptr_t rel, std::string schema_name, std::string table_name, + bool temporary) { rel->rel->Create(schema_name, table_name, temporary); } diff --git a/src/relational2.cpp b/src/relational2.cpp index 2cef9aa2e..626b98577 100644 --- a/src/relational2.cpp +++ b/src/relational2.cpp @@ -48,7 +48,8 @@ using namespace cpp11; auto rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); cpp11::writable::list prot = {rel}; - return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, rel->rel->Alias(alias)), con, df); + return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, rel->rel->Alias(alias)), + con, df); } // DuckDB Relations: operators @@ -73,7 +74,8 @@ using namespace cpp11; cpp11::writable::list prot = {rel}; - return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(filter)), con, df); + return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(filter)), con, + df); } [[cpp11::register]] SEXP rapi_reldf_project(data_frame df, duckdb::conn_eptr_t con, list exprs) { @@ -89,14 +91,14 @@ using namespace cpp11; projections.push_back(std::move(dexpr)); } - auto rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); auto projection = make_shared_ptr(rel->rel, std::move(projections), std::move(aliases)); cpp11::writable::list prot = {rel}; - return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(projection)), con, df); + return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(projection)), + con, df); } [[cpp11::register]] SEXP rapi_reldf_aggregate(data_frame df, duckdb::conn_eptr_t con, list groups, list aggregates) { @@ -127,10 +129,12 @@ using namespace cpp11; cpp11::writable::list prot = {rel}; - return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(aggregate)), con, df); + return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(aggregate)), con, + df); } -[[cpp11::register]] SEXP rapi_reldf_order(data_frame df, duckdb::conn_eptr_t con, list orders, r_vector ascending) { +[[cpp11::register]] SEXP rapi_reldf_order(data_frame df, duckdb::conn_eptr_t con, list orders, + r_vector ascending) { vector res_orders; OrderType order_type; @@ -148,11 +152,12 @@ using namespace cpp11; cpp11::writable::list prot = {rel}; - return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(order)), con, df); + return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(order)), con, + df); } [[cpp11::register]] SEXP rapi_reldf_join(data_frame left, data_frame right, duckdb::conn_eptr_t con, list conds, - std::string join, std::string join_ref_type) { + std::string join, std::string join_ref_type) { auto join_type = JoinType::INNER; auto ref_type = JoinRefType::REGULAR; unique_ptr cond; @@ -189,7 +194,8 @@ using namespace cpp11; ref_type = JoinRefType::CROSS; } auto res = make_shared_ptr(rel_left->rel, rel_right->rel, ref_type); - auto df = rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(res)), con, left); + auto df = rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(res)), + con, left); // if the user described filters, apply them on top of the cross product relation if (conds.size() > 0) { return rapi_reldf_filter(df, con, conds); @@ -208,7 +214,8 @@ using namespace cpp11; } auto res = make_shared_ptr(rel_left->rel, rel_right->rel, std::move(cond), join_type, ref_type); - return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(res)), con, left); + return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(res)), con, + left); } [[cpp11::register]] SEXP rapi_reldf_union_all(data_frame left, data_frame right, duckdb::conn_eptr_t con) { @@ -220,7 +227,8 @@ using namespace cpp11; auto setop = make_shared_ptr(rel_left->rel, rel_right->rel, SetOperationType::UNION); setop->setop_all = true; - return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(setop)), con, left); + return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(setop)), con, + left); } [[cpp11::register]] SEXP rapi_reldf_limit(data_frame df, duckdb::conn_eptr_t con, int64_t n) { @@ -228,7 +236,9 @@ using namespace cpp11; cpp11::writable::list prot = {rel}; - return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, make_shared_ptr(rel->rel, n, 0)), con, df); + return rapi_reldf_to_altrep( + make_external_prot("duckdb_relation", prot, make_shared_ptr(rel->rel, n, 0)), + con, df); } [[cpp11::register]] SEXP rapi_reldf_distinct(data_frame df, duckdb::conn_eptr_t con) { @@ -236,7 +246,9 @@ using namespace cpp11; cpp11::writable::list prot = {rel}; - return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, make_shared_ptr(rel->rel)), con, df); + return rapi_reldf_to_altrep( + make_external_prot("duckdb_relation", prot, make_shared_ptr(rel->rel)), con, + df); } [[cpp11::register]] SEXP rapi_reldf_set_intersect(data_frame left, data_frame right, duckdb::conn_eptr_t con) { @@ -247,7 +259,8 @@ using namespace cpp11; cpp11::writable::list prot = {rel_left, rel_right}; - return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(res)), con, left); + return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(res)), con, + left); } [[cpp11::register]] SEXP rapi_reldf_set_diff(data_frame left, data_frame right, duckdb::conn_eptr_t con) { @@ -258,7 +271,8 @@ using namespace cpp11; cpp11::writable::list prot = {rel_left, rel_right}; - return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(res)), con, left); + return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(res)), con, + left); } [[cpp11::register]] SEXP rapi_reldf_set_symdiff(data_frame left, data_frame right, duckdb::conn_eptr_t con) { @@ -273,7 +287,8 @@ using namespace cpp11; cpp11::writable::list prot = {rel_left, rel_right}; - return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(symdiff)), con, left); + return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(symdiff)), con, + left); } // DuckDB Relations: conversion @@ -284,21 +299,23 @@ using namespace cpp11; } auto rel = con->conn->RelationFromQuery(sql); cpp11::writable::list prot = {}; - return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(rel)), con, R_NilValue); + return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(rel)), con, + R_NilValue); } [[cpp11::register]] SEXP rapi_reldf_from_table(duckdb::conn_eptr_t con, const std::string schema_name, - const std::string table_name) { + const std::string table_name) { if (!con || !con.get() || !con->conn) { stop("rel_from_table: Invalid connection"); } auto rel = con->conn->Table(schema_name, table_name); cpp11::writable::list prot = {}; - return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(rel)), con, R_NilValue); + return rapi_reldf_to_altrep(make_external_prot("duckdb_relation", prot, std::move(rel)), con, + R_NilValue); } [[cpp11::register]] SEXP rapi_reldf_from_table_function(duckdb::conn_eptr_t con, const std::string function_name, - list positional_parameters_sexps, list named_parameters_sexps) { + list positional_parameters_sexps, list named_parameters_sexps) { if (!con || !con.get() || !con->conn) { stop("rel_from_table_function: Invalid connection"); } @@ -330,7 +347,8 @@ using namespace cpp11; return rapi_reldf_to_altrep(make_external("duckdb_relation", std::move(rel)), con, R_NilValue); } -[[cpp11::register]] SEXP rapi_reldf_explain(data_frame df, duckdb::conn_eptr_t con, std::string type, std::string format) { +[[cpp11::register]] SEXP rapi_reldf_explain(data_frame df, duckdb::conn_eptr_t con, std::string type, + std::string format) { auto type_enum = EnumUtil::FromString(type); auto format_enum = EnumUtil::FromString(format); @@ -339,22 +357,26 @@ using namespace cpp11; return result_to_df(rel->rel->Explain(type_enum, format_enum)); } -[[cpp11::register]] void rapi_reldf_to_parquet(data_frame df, duckdb::conn_eptr_t con, std::string file_name, list options_sexps) { +[[cpp11::register]] void rapi_reldf_to_parquet(data_frame df, duckdb::conn_eptr_t con, std::string file_name, + list options_sexps) { auto rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); rel->rel->WriteParquet(file_name, ListToVectorOfValue(options_sexps)); } -[[cpp11::register]] void rapi_reldf_to_csv(data_frame df, duckdb::conn_eptr_t con, std::string file_name, list options_sexps) { +[[cpp11::register]] void rapi_reldf_to_csv(data_frame df, duckdb::conn_eptr_t con, std::string file_name, + list options_sexps) { auto rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); rel->rel->WriteCSV(file_name, ListToVectorOfValue(options_sexps)); } -[[cpp11::register]] void rapi_reldf_to_table(data_frame df, duckdb::conn_eptr_t con, std::string schema_name, std::string table_name, bool temporary) { +[[cpp11::register]] void rapi_reldf_to_table(data_frame df, duckdb::conn_eptr_t con, std::string schema_name, + std::string table_name, bool temporary) { auto rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); rel->rel->Create(schema_name, table_name, temporary); } -[[cpp11::register]] void rapi_reldf_insert(data_frame df, duckdb::conn_eptr_t con, std::string schema_name, std::string table_name) { +[[cpp11::register]] void rapi_reldf_insert(data_frame df, duckdb::conn_eptr_t con, std::string schema_name, + std::string table_name) { auto rel = cpp11::as_cpp>(rapi_rel_from_any_df(con, df, true)); rel->rel->Insert(schema_name, table_name); } diff --git a/src/reltoaltrep.cpp b/src/reltoaltrep.cpp index 39e78c226..1ec05658e 100644 --- a/src/reltoaltrep.cpp +++ b/src/reltoaltrep.cpp @@ -103,10 +103,8 @@ AltrepRelationWrapper *AltrepRelationWrapper::Get(SEXP x) { return GetFromExternalPtr(x); } -AltrepRelationWrapper::AltrepRelationWrapper(rel_extptr_t rel_, size_t n_rows_, - size_t n_cells_, SEXP df_) - : n_rows(n_rows_), n_cells(n_cells_), rel_eptr(rel_), - rel(rel_->rel), df(df_) { +AltrepRelationWrapper::AltrepRelationWrapper(rel_extptr_t rel_, size_t n_rows_, size_t n_cells_, SEXP df_) + : n_rows(n_rows_), n_cells(n_cells_), rel_eptr(rel_), rel(rel_->rel), df(df_) { } bool AltrepRelationWrapper::HasQueryResult() const { @@ -245,7 +243,7 @@ struct AltrepVectorWrapper { dest_offset += chunk.size(); } } - return (void*)DATAPTR_RO(transformed_vector); + return (void *)DATAPTR_RO(transformed_vector); } SEXP Vector() { @@ -423,8 +421,8 @@ size_t DoubleToSize(double d) { // convert to SEXP (void)(SEXP)data_frame; - auto relation_wrapper = make_shared_ptr(rel, DoubleToSize(n_rows), - DoubleToSize(n_cells), data_frame); + auto relation_wrapper = + make_shared_ptr(rel, DoubleToSize(n_rows), DoubleToSize(n_cells), data_frame); for (size_t col_idx = 0; col_idx < ncols; col_idx++) { auto &column_type = drel->Columns()[col_idx].Type(); @@ -456,7 +454,6 @@ size_t DoubleToSize(double d) { return data_frame; } - SEXP rapi_reldf_to_altrep(duckdb::rel_extptr_t rel, duckdb::conn_eptr_t con, cpp11::list template_) { D_ASSERT(rel && rel->rel); auto drel = rel->rel; @@ -467,7 +464,8 @@ SEXP rapi_reldf_to_altrep(duckdb::rel_extptr_t rel, duckdb::conn_eptr_t con, cpp auto template_wrapper_args = rapi_rel_wrapper_args_from_altrep_df(template_); - auto relation_wrapper = make_shared_ptr(rel, template_wrapper_args.first, template_wrapper_args.second, data_frame); + auto relation_wrapper = make_shared_ptr(rel, template_wrapper_args.first, + template_wrapper_args.second, data_frame); // convert to SEXP (void)(SEXP)data_frame; From 506844ecbacaf213c83343625dbfec6fcad6760e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Tue, 11 Mar 2025 17:37:18 +0100 Subject: [PATCH 68/69] FIXME --- src/include/reltoaltrep.hpp | 2 ++ src/reltoaltrep.cpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/include/reltoaltrep.hpp b/src/include/reltoaltrep.hpp index 606c88c3a..271534fbd 100644 --- a/src/include/reltoaltrep.hpp +++ b/src/include/reltoaltrep.hpp @@ -22,6 +22,8 @@ struct AltrepRelationWrapper { rel_extptr_t rel_eptr; duckdb::shared_ptr rel; + + // FIXME: Does this need to be here? cpp11::sexp df; duckdb::unique_ptr mat_result; diff --git a/src/reltoaltrep.cpp b/src/reltoaltrep.cpp index 1ec05658e..fa99ca6ae 100644 --- a/src/reltoaltrep.cpp +++ b/src/reltoaltrep.cpp @@ -464,6 +464,8 @@ SEXP rapi_reldf_to_altrep(duckdb::rel_extptr_t rel, duckdb::conn_eptr_t con, cpp auto template_wrapper_args = rapi_rel_wrapper_args_from_altrep_df(template_); + // FIXME: Construct AltrepDataFrameRelation + auto relation_wrapper = make_shared_ptr(rel, template_wrapper_args.first, template_wrapper_args.second, data_frame); From 21a67f9a3250cb3b2ad1e18b89bc1dd945390c67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Tue, 11 Mar 2025 17:37:23 +0100 Subject: [PATCH 69/69] const cast --- src/reltoaltrep.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/reltoaltrep.cpp b/src/reltoaltrep.cpp index fa99ca6ae..1ca3c8913 100644 --- a/src/reltoaltrep.cpp +++ b/src/reltoaltrep.cpp @@ -243,7 +243,7 @@ struct AltrepVectorWrapper { dest_offset += chunk.size(); } } - return (void *)DATAPTR_RO(transformed_vector); + return const_castDATAPTR_RO(transformed_vector); } SEXP Vector() {