Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions R/cpp11.R
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,8 @@ rapi_rel_set_symdiff <- function(rel_a, rel_b) {
.Call(`_duckdb_rapi_rel_set_symdiff`, rel_a, rel_b)
}

rapi_rel_from_sql <- function(con, sql) {
.Call(`_duckdb_rapi_rel_from_sql`, con, sql)
rapi_rel_from_sql <- function(con, sql, env) {
.Call(`_duckdb_rapi_rel_from_sql`, con, sql, env)
}

rapi_rel_from_table <- function(con, schema_name, table_name) {
Expand Down
4 changes: 2 additions & 2 deletions R/relational.R
Original file line number Diff line number Diff line change
Expand Up @@ -480,8 +480,8 @@ rel_to_sql <- function(rel) {
#' con <- DBI::dbConnect(duckdb())
#' DBI::dbWriteTable(con, "mtcars", mtcars)
#' rel <- rel_from_sql(con, "SELECT * FROM mtcars")
rel_from_sql <- function(con, sql) {
rethrow_rapi_rel_from_sql(con@conn_ref, sql)
rel_from_sql <- function(con, sql, env = parent.frame()) {
rethrow_rapi_rel_from_sql(con@conn_ref, sql, env)
}

#' Create a duckdb table relation from a table name
Expand Down
4 changes: 2 additions & 2 deletions R/rethrow-gen.R
Original file line number Diff line number Diff line change
Expand Up @@ -333,9 +333,9 @@ rethrow_rapi_rel_set_symdiff <- function(rel_a, rel_b, call = parent.frame(2)) {
)
}

rethrow_rapi_rel_from_sql <- function(con, sql, call = parent.frame(2)) {
rethrow_rapi_rel_from_sql <- function(con, sql, env, call = parent.frame(2)) {
rlang::try_fetch(
rapi_rel_from_sql(con, sql),
rapi_rel_from_sql(con, sql, env),
error = function(e) {
rethrow_error_from_rapi(e, call)
}
Expand Down
8 changes: 4 additions & 4 deletions src/cpp11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -273,10 +273,10 @@ extern "C" SEXP _duckdb_rapi_rel_set_symdiff(SEXP rel_a, SEXP rel_b) {
END_CPP11
}
// relational.cpp
SEXP rapi_rel_from_sql(duckdb::conn_eptr_t con, const std::string sql);
extern "C" SEXP _duckdb_rapi_rel_from_sql(SEXP con, SEXP sql) {
SEXP rapi_rel_from_sql(duckdb::conn_eptr_t con, const std::string sql, SEXP env);
extern "C" SEXP _duckdb_rapi_rel_from_sql(SEXP con, SEXP sql, SEXP env) {
BEGIN_CPP11
return cpp11::as_sexp(rapi_rel_from_sql(cpp11::as_cpp<cpp11::decay_t<duckdb::conn_eptr_t>>(con), cpp11::as_cpp<cpp11::decay_t<const std::string>>(sql)));
return cpp11::as_sexp(rapi_rel_from_sql(cpp11::as_cpp<cpp11::decay_t<duckdb::conn_eptr_t>>(con), cpp11::as_cpp<cpp11::decay_t<const std::string>>(sql), cpp11::as_cpp<cpp11::decay_t<SEXP>>(env)));
END_CPP11
}
// relational.cpp
Expand Down Expand Up @@ -466,7 +466,7 @@ static const R_CallMethodDef CallEntries[] = {
{"_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, 4},
{"_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_sql", (DL_FUNC) &_duckdb_rapi_rel_from_sql, 3},
{"_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},
Expand Down
20 changes: 17 additions & 3 deletions src/relational.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "reltoaltrep.hpp"

#include "R_ext/Random.h"
#include "httplib.hpp"

#include "duckdb/parser/expression/columnref_expression.hpp"
#include "duckdb/parser/expression/constant_expression.hpp"
Expand Down Expand Up @@ -469,12 +470,25 @@ bool constant_expression_is_not_null(duckdb::expr_extptr_t expr) {
//
// DuckDB Relations: conversion

[[cpp11::register]] SEXP rapi_rel_from_sql(duckdb::conn_eptr_t con, const std::string sql) {
[[cpp11::register]] SEXP rapi_rel_from_sql(duckdb::conn_eptr_t con, const std::string sql, SEXP env) {
if (!con || !con.get() || !con->conn) {
stop("rel_from_table: Invalid connection");
stop("rel_from_sql: Invalid connection");
}

D_ASSERT(con->db->env == R_NilValue);
con->db->env = (SEXP)env;
con->db->registered_dfs = Rf_cons(R_NilValue, R_NilValue);
duckdb_httplib::detail::scope_exit reset_db_env([&]() {
con->db->env = R_NilValue;
con->db->registered_dfs = R_NilValue;
});

// Possible FIXME (but anti-pattern):
// Prepend a WITH clause to the query to register the data frames.
// Better FIXME: RelationFromQuery() binds the data frames in the query.

auto rel = con->conn->RelationFromQuery(sql);
cpp11::writable::list prot = {};
cpp11::writable::list prot = { con->db->registered_dfs };
return make_external_prot<RelationWrapper>("duckdb_relation", prot, std::move(rel));
}

Expand Down
Loading