Skip to content

Commit 64c6560

Browse files
committed
feat: New env argument to rel_from_sql()
1 parent f6bcc38 commit 64c6560

File tree

5 files changed

+27
-13
lines changed

5 files changed

+27
-13
lines changed

R/cpp11.R

+2-2
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,8 @@ rapi_rel_set_symdiff <- function(rel_a, rel_b) {
148148
.Call(`_duckdb_rapi_rel_set_symdiff`, rel_a, rel_b)
149149
}
150150

151-
rapi_rel_from_sql <- function(con, sql) {
152-
.Call(`_duckdb_rapi_rel_from_sql`, con, sql)
151+
rapi_rel_from_sql <- function(con, sql, env) {
152+
.Call(`_duckdb_rapi_rel_from_sql`, con, sql, env)
153153
}
154154

155155
rapi_rel_from_table <- function(con, schema_name, table_name) {

R/relational.R

+2-2
Original file line numberDiff line numberDiff line change
@@ -480,8 +480,8 @@ rel_to_sql <- function(rel) {
480480
#' con <- DBI::dbConnect(duckdb())
481481
#' DBI::dbWriteTable(con, "mtcars", mtcars)
482482
#' rel <- rel_from_sql(con, "SELECT * FROM mtcars")
483-
rel_from_sql <- function(con, sql) {
484-
rethrow_rapi_rel_from_sql(con@conn_ref, sql)
483+
rel_from_sql <- function(con, sql, env = parent.frame()) {
484+
rethrow_rapi_rel_from_sql(con@conn_ref, sql, env)
485485
}
486486

487487
#' Create a duckdb table relation from a table name

R/rethrow-gen.R

+2-2
Original file line numberDiff line numberDiff line change
@@ -333,9 +333,9 @@ rethrow_rapi_rel_set_symdiff <- function(rel_a, rel_b, call = parent.frame(2)) {
333333
)
334334
}
335335

336-
rethrow_rapi_rel_from_sql <- function(con, sql, call = parent.frame(2)) {
336+
rethrow_rapi_rel_from_sql <- function(con, sql, env, call = parent.frame(2)) {
337337
rlang::try_fetch(
338-
rapi_rel_from_sql(con, sql),
338+
rapi_rel_from_sql(con, sql, env),
339339
error = function(e) {
340340
rethrow_error_from_rapi(e, call)
341341
}

src/cpp11.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -273,10 +273,10 @@ extern "C" SEXP _duckdb_rapi_rel_set_symdiff(SEXP rel_a, SEXP rel_b) {
273273
END_CPP11
274274
}
275275
// relational.cpp
276-
SEXP rapi_rel_from_sql(duckdb::conn_eptr_t con, const std::string sql);
277-
extern "C" SEXP _duckdb_rapi_rel_from_sql(SEXP con, SEXP sql) {
276+
SEXP rapi_rel_from_sql(duckdb::conn_eptr_t con, const std::string sql, SEXP env);
277+
extern "C" SEXP _duckdb_rapi_rel_from_sql(SEXP con, SEXP sql, SEXP env) {
278278
BEGIN_CPP11
279-
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)));
279+
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)));
280280
END_CPP11
281281
}
282282
// relational.cpp
@@ -458,7 +458,7 @@ static const R_CallMethodDef CallEntries[] = {
458458
{"_duckdb_rapi_rel_filter", (DL_FUNC) &_duckdb_rapi_rel_filter, 2},
459459
{"_duckdb_rapi_rel_from_altrep_df", (DL_FUNC) &_duckdb_rapi_rel_from_altrep_df, 4},
460460
{"_duckdb_rapi_rel_from_df", (DL_FUNC) &_duckdb_rapi_rel_from_df, 3},
461-
{"_duckdb_rapi_rel_from_sql", (DL_FUNC) &_duckdb_rapi_rel_from_sql, 2},
461+
{"_duckdb_rapi_rel_from_sql", (DL_FUNC) &_duckdb_rapi_rel_from_sql, 3},
462462
{"_duckdb_rapi_rel_from_table", (DL_FUNC) &_duckdb_rapi_rel_from_table, 3},
463463
{"_duckdb_rapi_rel_from_table_function", (DL_FUNC) &_duckdb_rapi_rel_from_table_function, 4},
464464
{"_duckdb_rapi_rel_insert", (DL_FUNC) &_duckdb_rapi_rel_insert, 3},

src/relational.cpp

+17-3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "reltoaltrep.hpp"
55

66
#include "R_ext/Random.h"
7+
#include "httplib.hpp"
78

89
#include "duckdb/parser/expression/columnref_expression.hpp"
910
#include "duckdb/parser/expression/constant_expression.hpp"
@@ -469,12 +470,25 @@ bool constant_expression_is_not_null(duckdb::expr_extptr_t expr) {
469470
//
470471
// DuckDB Relations: conversion
471472

472-
[[cpp11::register]] SEXP rapi_rel_from_sql(duckdb::conn_eptr_t con, const std::string sql) {
473+
[[cpp11::register]] SEXP rapi_rel_from_sql(duckdb::conn_eptr_t con, const std::string sql, SEXP env) {
473474
if (!con || !con.get() || !con->conn) {
474-
stop("rel_from_table: Invalid connection");
475+
stop("rel_from_sql: Invalid connection");
475476
}
477+
478+
D_ASSERT(con->db->env == R_NilValue);
479+
con->db->env = (SEXP)env;
480+
con->db->registered_dfs = Rf_cons(R_NilValue, R_NilValue);
481+
duckdb_httplib::detail::scope_exit reset_db_env([&]() {
482+
con->db->env = R_NilValue;
483+
con->db->registered_dfs = R_NilValue;
484+
});
485+
486+
// Possible FIXME (but anti-pattern):
487+
// Prepend a WITH clause to the query to register the data frames.
488+
// Better FIXME: RelationFromQuery() binds the data frames in the query.
489+
476490
auto rel = con->conn->RelationFromQuery(sql);
477-
cpp11::writable::list prot = {};
491+
cpp11::writable::list prot = { con->db->registered_dfs };
478492
return make_external_prot<RelationWrapper>("duckdb_relation", prot, std::move(rel));
479493
}
480494

0 commit comments

Comments
 (0)