diff --git a/R/cpp11.R b/R/cpp11.R index 3d1311eb5..b556dc235 100644 --- a/R/cpp11.R +++ b/R/cpp11.R @@ -156,6 +156,10 @@ 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_table <- function(con, schema_name, table_name) { .Call(`_duckdb_rapi_rel_from_table`, con, schema_name, table_name) } diff --git a/R/relational.R b/R/relational.R index 903932720..efc536022 100644 --- a/R/relational.R +++ b/R/relational.R @@ -148,7 +148,7 @@ rel_aggregate <- rapi_rel_aggregate #' 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. +#' @param ascending a vector of boolean values describing sort order of expressions. True for ascending. #' @return the now aggregated `duckdb_relation` object #' @noRd #' @examples @@ -163,7 +163,7 @@ rel_order <- function(rel, orders, ascending = NULL) { if (length(orders) != length(ascending)) { stop("length of ascending must equal length of orders") } - + return(rapi_rel_order(rel, orders, ascending)) } @@ -385,6 +385,18 @@ rel_to_sql <- rapi_rel_to_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_sql <- function(con, sql) { + rapi_rel_from_sql(con@conn_ref, sql) +} + #' Create a duckdb table relation from a table name #' @param table the table name #' @return a duckdb relation @@ -393,7 +405,7 @@ rel_to_sql <- rapi_rel_to_sql #' con <- DBI::dbConnect(duckdb()) #' DBI::dbWriteTable(con, "mtcars", mtcars) #' rel <- rel_from_table(con, "mtcars") -rel_from_table <- function(con, table_name, schema_name="MAIN") { +rel_from_table <- function(con, table_name, schema_name = "MAIN") { rapi_rel_from_table(con@conn_ref, schema_name, table_name) } diff --git a/src/cpp11.cpp b/src/cpp11.cpp index 67a17d523..2d18b08b8 100644 --- a/src/cpp11.cpp +++ b/src/cpp11.cpp @@ -287,6 +287,13 @@ 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) { + BEGIN_CPP11 + return cpp11::as_sexp(rapi_rel_from_sql(cpp11::as_cpp>(con), cpp11::as_cpp>(sql))); + END_CPP11 +} +// relational.cpp SEXP rapi_rel_from_table(duckdb::conn_eptr_t con, const std::string schema_name, const std::string table_name); extern "C" SEXP _duckdb_rapi_rel_from_table(SEXP con, SEXP schema_name, SEXP table_name) { BEGIN_CPP11 @@ -451,6 +458,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, 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_join", (DL_FUNC) &_duckdb_rapi_rel_join, 5}, diff --git a/src/relational.cpp b/src/relational.cpp index 65410d340..eece4b170 100644 --- a/src/relational.cpp +++ b/src/relational.cpp @@ -490,12 +490,20 @@ static SEXP result_to_df(duckdb::unique_ptr res) { return make_external_prot("duckdb_relation", prot, symdiff); } +[[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"); + } + auto rel = con->conn->RelationFromQuery(sql); + cpp11::writable::list prot = {}; + return make_external_prot("duckdb_relation", prot, std::move(rel)); +} + [[cpp11::register]] SEXP rapi_rel_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 desc = make_uniq(); auto rel = con->conn->Table(schema_name, table_name); cpp11::writable::list prot = {}; return make_external_prot("duckdb_relation", prot, std::move(rel));