Skip to content

Commit

Permalink
Merge 167880e into 10b3416
Browse files Browse the repository at this point in the history
  • Loading branch information
romainfrancois committed Feb 23, 2024
2 parents 10b3416 + 167880e commit 68460ac
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/include/rapi.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,18 @@

#include <Rdefines.h>
#include <R_ext/Altrep.h>
#include <Rversion.h>

#include "duckdb.hpp"
#include "duckdb/function/table_function.hpp"
#include "duckdb/common/unordered_map.hpp"
#include "duckdb/parser/tableref/table_function_ref.hpp"
#include "duckdb/common/mutex.hpp"

#if defined(R_VERSION) && R_VERSION >= R_Version(4, 3, 0)
#define R_HAS_ALTLIST
#endif

namespace duckdb {

typedef unordered_map<std::string, SEXP> arrow_scans_t;
Expand Down
6 changes: 6 additions & 0 deletions src/include/reltoaltrep.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,10 @@ struct RelToAltrep {
static R_altrep_class_t int_class;
static R_altrep_class_t real_class;
static R_altrep_class_t string_class;

#if defined(R_HAS_ALTLIST)
static SEXP VectorListElt(SEXP x, R_xlen_t i);
static R_altrep_class_t list_class;
#endif

};
27 changes: 27 additions & 0 deletions src/reltoaltrep.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ R_altrep_class_t RelToAltrep::int_class;
R_altrep_class_t RelToAltrep::real_class;
R_altrep_class_t RelToAltrep::string_class;

#if defined(R_HAS_ALTLIST)
R_altrep_class_t RelToAltrep::list_class;
#endif

void RelToAltrep::Initialize(DllInfo *dll) {
// this is a string so setting row names will not lead to materialization
rownames_class = R_make_altinteger_class("reltoaltrep_rownames_class", "duckdb", dll);
Expand Down Expand Up @@ -40,6 +44,15 @@ void RelToAltrep::Initialize(DllInfo *dll) {
R_set_altvec_Dataptr_or_null_method(rownames_class, RownamesDataptrOrNull);

R_set_altstring_Elt_method(string_class, VectorStringElt);

#if defined(R_HAS_ALTLIST)
list_class = R_make_altlist_class("reltoaltrep_list_class", "duckdb", dll);
R_set_altrep_Inspect_method(list_class, RelInspect);
R_set_altrep_Length_method(list_class, VectorLength);
R_set_altvec_Dataptr_method(list_class, VectorDataptr);
R_set_altlist_Elt_method(list_class, VectorListElt);
#endif

}

template <class T>
Expand Down Expand Up @@ -231,6 +244,14 @@ SEXP RelToAltrep::VectorStringElt(SEXP x, R_xlen_t i) {
END_CPP11
}

#if defined(R_HAS_ALTLIST)
SEXP RelToAltrep::VectorListElt(SEXP x, R_xlen_t i) {
BEGIN_CPP11
return VECTOR_ELT(AltrepVectorWrapper::Get(x)->Vector(), i);
END_CPP11
}
#endif

static R_altrep_class_t LogicalTypeToAltrepType(const LogicalType &type) {
switch (type.id()) {
case LogicalTypeId::BOOLEAN:
Expand Down Expand Up @@ -261,6 +282,12 @@ static R_altrep_class_t LogicalTypeToAltrepType(const LogicalType &type) {
case LogicalTypeId::VARCHAR:
case LogicalTypeId::UUID:
return RelToAltrep::string_class;

#if defined(R_HAS_ALTLIST)
case LogicalTypeId::LIST:
return RelToAltrep::list_class;
#endif

default:
cpp11::stop("rel_to_altrep: Unknown column type for altrep: %s", type.ToString().c_str());
}
Expand Down
15 changes: 15 additions & 0 deletions tests/testthat/test_list.R
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,18 @@ test_that("one-level lists can be read", {
res <- dbGetQuery(con, "SELECT ['Hello', 'World'] a union all select ['There']")$a
expect_equal(res, list(c("Hello", "World"), c("There")))
})

test_that("rel_filter() handles LIST logical type", {
skip_if_not(getRversion() >= "4.3.0")

con <- dbConnect(duckdb())
on.exit(dbDisconnect(con, shutdown = TRUE))

df1 <- tibble::tibble(a = list(1, c(1,2)))

rel1 <- rel_from_df(con, df1)
rel2 <- rel_filter(rel1, list(expr_constant(TRUE)))

df2 <- rel_to_altrep(rel2)
expect_equal(df1$a, df2$a)
})

0 comments on commit 68460ac

Please sign in to comment.