This is an automated email from the ASF dual-hosted git repository.
paleolimbot pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-adbc.git
The following commit(s) were added to refs/heads/main by this push:
new a9c381d2 fix(r/adbcdrivermanager): Ensure nullable arguments
`adbc_connection_get_objects()` can be specified (#1032)
a9c381d2 is described below
commit a9c381d2203b28558739f99a8e770d6ab6a50b66
Author: Dewey Dunnington <[email protected]>
AuthorDate: Fri Sep 8 13:38:53 2023 -0300
fix(r/adbcdrivermanager): Ensure nullable arguments
`adbc_connection_get_objects()` can be specified (#1032)
Thanks to @nbenn for the reprex!
``` r
library(adbcdrivermanager)
db <- adbc_database_init(adbcsqlite::adbcsqlite(), uri = ":memory:")
con <- adbc_connection_init(db)
flights <- nycflights13::flights
flights$time_hour <- NULL
write_adbc(flights, con, "flights")
stream <- adbc_connection_get_objects(con)
# pretty wild result type
df <- as.data.frame(stream)
df$catalog_db_schemas[[1]]$db_schema_tables[[1]]$table_name
#> [1] "flights"
df$catalog_db_schemas[[1]]$db_schema_tables[[1]]$table_columns[[1]]$column_name
#> [1] "year" "month" "day" "dep_time"
#> [5] "sched_dep_time" "dep_delay" "arr_time" "sched_arr_time"
#> [9] "arr_delay" "carrier" "flight" "tailnum"
#> [13] "origin" "dest" "air_time" "distance"
#> [17] "hour" "minute"
```
<sup>Created on 2023-09-01 with [reprex
v2.0.2](https://reprex.tidyverse.org)</sup>
---
r/adbcdrivermanager/R/adbc.R | 4 ++--
.../man/adbc_connection_get_info.Rd | 12 +++++------
r/adbcdrivermanager/src/radbc.cc | 23 ++++++++++++++++------
r/adbcdrivermanager/src/radbc.h | 6 +++++-
4 files changed, 30 insertions(+), 15 deletions(-)
diff --git a/r/adbcdrivermanager/R/adbc.R b/r/adbcdrivermanager/R/adbc.R
index 2e25424a..cf711e02 100644
--- a/r/adbcdrivermanager/R/adbc.R
+++ b/r/adbcdrivermanager/R/adbc.R
@@ -226,8 +226,8 @@ adbc_connection_get_info <- function(connection,
info_codes) {
#' @rdname adbc_connection_get_info
#' @export
-adbc_connection_get_objects <- function(connection, depth, catalog, db_schema,
- table_name, table_type, column_name) {
+adbc_connection_get_objects <- function(connection, depth = 0L, catalog =
NULL, db_schema = NULL,
+ table_name = NULL, table_type = NULL,
column_name = NULL) {
error <- adbc_allocate_error()
out_stream <- nanoarrow::nanoarrow_allocate_array_stream()
status <- .Call(
diff --git a/r/adbcdrivermanager/man/adbc_connection_get_info.Rd
b/r/adbcdrivermanager/man/adbc_connection_get_info.Rd
index 451a9b0f..b4fb89d9 100644
--- a/r/adbcdrivermanager/man/adbc_connection_get_info.Rd
+++ b/r/adbcdrivermanager/man/adbc_connection_get_info.Rd
@@ -14,12 +14,12 @@ adbc_connection_get_info(connection, info_codes)
adbc_connection_get_objects(
connection,
- depth,
- catalog,
- db_schema,
- table_name,
- table_type,
- column_name
+ depth = 0L,
+ catalog = NULL,
+ db_schema = NULL,
+ table_name = NULL,
+ table_type = NULL,
+ column_name = NULL
)
adbc_connection_get_table_schema(connection, catalog, db_schema, table_name)
diff --git a/r/adbcdrivermanager/src/radbc.cc b/r/adbcdrivermanager/src/radbc.cc
index 224c7f81..5d080cbd 100644
--- a/r/adbcdrivermanager/src/radbc.cc
+++ b/r/adbcdrivermanager/src/radbc.cc
@@ -274,10 +274,11 @@ extern "C" SEXP RAdbcConnectionGetObjects(SEXP
connection_xptr, SEXP depth_sexp,
SEXP error_xptr) {
auto connection = adbc_from_xptr<AdbcConnection>(connection_xptr);
int depth = adbc_as_int(depth_sexp);
- const char* catalog = adbc_as_const_char(catalog_sexp);
- const char* db_schema = adbc_as_const_char(db_schema_sexp);
- const char* table_name = adbc_as_const_char(table_name_sexp);
+ const char* catalog = adbc_as_const_char(catalog_sexp, true);
+ const char* db_schema = adbc_as_const_char(db_schema_sexp, true);
+ const char* table_name = adbc_as_const_char(table_name_sexp, true);
+ // Build the null-terminated const char** used to filter by table type
int table_type_length = Rf_length(table_type_sexp);
SEXP table_type_shelter =
PROTECT(Rf_allocVector(RAWSXP, (table_type_length + 1) * sizeof(const
char*)));
@@ -287,12 +288,22 @@ extern "C" SEXP RAdbcConnectionGetObjects(SEXP
connection_xptr, SEXP depth_sexp,
}
table_type[table_type_length] = nullptr;
- const char* column_name = adbc_as_const_char(column_name_sexp);
+ // Ensure that R_NilValue maps to null and not a null-termianted const char**
+ // of length 0.
+ const char** table_type_maybe_null;
+ if (table_type_sexp == R_NilValue) {
+ table_type_maybe_null = nullptr;
+ } else {
+ table_type_maybe_null = table_type;
+ }
+
+ const char* column_name = adbc_as_const_char(column_name_sexp, true);
auto out_stream = adbc_from_xptr<ArrowArrayStream>(out_stream_xptr);
auto error = adbc_from_xptr<AdbcError>(error_xptr);
- int status = AdbcConnectionGetObjects(connection, depth, catalog, db_schema,
table_name,
- table_type, column_name, out_stream,
error);
+ int status =
+ AdbcConnectionGetObjects(connection, depth, catalog, db_schema,
table_name,
+ table_type_maybe_null, column_name, out_stream,
error);
UNPROTECT(1);
return adbc_wrap_status(status);
}
diff --git a/r/adbcdrivermanager/src/radbc.h b/r/adbcdrivermanager/src/radbc.h
index 9baf8d6d..9c20686d 100644
--- a/r/adbcdrivermanager/src/radbc.h
+++ b/r/adbcdrivermanager/src/radbc.h
@@ -131,7 +131,11 @@ static inline void adbc_xptr_move_attrs(SEXP xptr_old,
SEXP xptr_new) {
UNPROTECT(5);
}
-static inline const char* adbc_as_const_char(SEXP sexp) {
+static inline const char* adbc_as_const_char(SEXP sexp, bool nullable = false)
{
+ if (nullable && sexp == R_NilValue) {
+ return nullptr;
+ }
+
if (TYPEOF(sexp) != STRSXP || Rf_length(sexp) != 1) {
Rf_error("Expected character(1) for conversion to const char*");
}