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
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: tiledb
Type: Package
Version: 0.31.1
Version: 0.31.1.1
Title: Modern Database Engine for Complex Data Based on Multi-Dimensional Arrays
Authors@R: c(
person("TileDB, Inc.", role = c("aut", "cph")),
Expand Down
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ export(tiledb_query_condition)
export(tiledb_query_condition_combine)
export(tiledb_query_condition_create)
export(tiledb_query_condition_init)
export(tiledb_query_condition_negate)
export(tiledb_query_condition_set_use_enumeration)
export(tiledb_query_create_buffer_ptr)
export(tiledb_query_create_buffer_ptr_char)
Expand Down
4 changes: 4 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# tiledb 0.31.2

* Add `tiledb_query_condition_negate()` function to act as a `NOT` operator for query conditions [#819](https://github.com/TileDB-Inc/TileDB-R/pull/819)

# tiledb 0.31.1

* Allow `parse_query_condition()` to work on dimensions when an array is passed
Expand Down
34 changes: 28 additions & 6 deletions R/QueryCondition.R
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,11 @@ tiledb_query_condition_init <- function(attr, value, dtype, op, qc = tiledb_quer

#' Combine two 'tiledb_query_condition' objects
#'
#' Combines two query condition object using a relatiional operator. Support for operator
#' 'AND' is generally available, the 'OR' operator is available if TileDB 2.10 or newer is
#' used.
#' Combines two query condition objects using a relational operator. Support for operator
#' 'AND' is generally available. The 'OR' operator is available in TileDB 2.10 and later.
#' @param lhs A 'tiledb_query_condition' object on the left-hand side of the relation
#' @param rhs A 'tiledb_query_condition' object on the left-hand side of the relation
#' @param op A character value with then relation, this must be one of 'AND', 'OR' or 'NOT'.
#' @param op A character value with then relation, this must be one of 'AND' or 'OR'.
#' @return The combined 'tiledb_query_condition' object
#' @export
tiledb_query_condition_combine <- function(lhs, rhs, op) {
Expand All @@ -100,13 +99,29 @@ tiledb_query_condition_combine <- function(lhs, rhs, op) {
"Argument 'rhs' must be a query condition object" = is(rhs, "tiledb_query_condition"),
"Argument 'op' must be a character" = is.character(op)
)
op <- match.arg(op, c("AND", "OR", "NOT"))
op <- match.arg(op, c("AND", "OR"))
qc <- tiledb_query_condition()
qc@ptr <- libtiledb_query_condition_combine(lhs@ptr, rhs@ptr, op)
qc@init <- TRUE
invisible(qc)
}

#' Negate a 'tiledb_query_condition' object
#'
#' Takes a query condition object and negates it, similar to the '!' operator.
#' @param qc A 'tiledb_query_condition' object to negate
#' @return The negated 'tiledb_query_condition' object
#' @export
tiledb_query_condition_negate <- function(qc) {
stopifnot(
"Argument 'qc' must be a query condition object" = is(qc, "tiledb_query_condition")
)
res <- tiledb_query_condition()
res@ptr <- libtiledb_query_condition_negate(qc@ptr)
res@init <- TRUE
invisible(res)
}

#' Create a 'tiledb_query_condition' object from an expression
#'
#' The grammar for query conditions is at present constraint to eight operators (\code{">"},
Expand Down Expand Up @@ -150,7 +165,8 @@ parse_query_condition <- function(expr, ta = NULL, debug = FALSE, strict = TRUE,
if (.hasArray && length(ta@sil) == 0) ta@sil <- .fill_schema_info_list(ta@uri)
`%!in%` <- Negate(`%in%`)
.isComparisonOperator <- function(x) tolower(as.character(x)) %in% c(">", ">=", "<", "<=", "==", "!=", "%in%", "%nin%")
.isBooleanOperator <- function(x) as.character(x) %in% c("&&", "||", "!", "&", "|")
.isBooleanOperator <- function(x) as.character(x) %in% c("&&", "||", "&", "|")
.isNegationOperator <- function(x) as.character(x) == "!"
.isAscii <- function(x) grepl("^[[:alnum:]_]+$", x)
.isInteger <- function(x) grepl("^[[:digit:]]+$", as.character(x))
.isDouble <- function(x) grepl("^[[:digit:]\\.]+$", as.character(x)) && length(grepRaw(".", as.character(x), fixed = TRUE, all = TRUE)) == 1
Expand Down Expand Up @@ -224,6 +240,12 @@ parse_query_condition <- function(expr, ta = NULL, debug = FALSE, strict = TRUE,
.makeExpr(x[[3]]),
.mapBoolToCharacter(as.character(x[1]))
)
} else if (.isNegationOperator(x[1])) {
if (debug) {
cat(" ![", as.character(x[2]), "]")
}
.makeExpr(x[[2]], debug = debug)
tiledb_query_condition_negate(.makeExpr(x[[2]]))
} else if (.isInOperator(x[1])) {
if (debug) {
cat("in: [", as.character(x[2]), "]",
Expand Down
4 changes: 4 additions & 0 deletions R/RcppExports.R
Original file line number Diff line number Diff line change
Expand Up @@ -825,6 +825,10 @@ libtiledb_query_condition_combine <- function(lhs, rhs, str) {
.Call(`_tiledb_libtiledb_query_condition_combine`, lhs, rhs, str)
}

libtiledb_query_condition_negate <- function(qc) {
.Call(`_tiledb_libtiledb_query_condition_negate`, qc)
}

libtiledb_query_condition_set_use_enumeration <- function(ctx, cond, use_enumeration) {
invisible(.Call(`_tiledb_libtiledb_query_condition_set_use_enumeration`, ctx, cond, use_enumeration))
}
Expand Down
21 changes: 21 additions & 0 deletions inst/tinytest/test_querycondition.R
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,27 @@ expect_equal(nrow(ndf), 18)
tiledb_array_close(arr)
rm(qry)

## check the negative of the previous condition
qry <- tiledb_query(arr, "READ")
rows <- integer(20)
cola <- integer(20)
colb <- numeric(20)
tiledb_query_set_buffer(qry, "__tiledb_rows", rows)
tiledb_query_set_buffer(qry, "a", cola)
tiledb_query_set_buffer(qry, "b", colb)
lhs <- tiledb_query_condition_init("a", 2L, "INT32", "NE")
rhs <- tiledb_query_condition_init("a", 12L, "INT32", "NE")
qc <- tiledb_query_condition_combine(lhs, rhs, "AND")
qc_inv <- tiledb_query_condition_negate(qc)
qry <- tiledb_query_set_condition(qry, qc_inv)
tiledb_query_submit(qry)
tiledb_query_finalize(qry)
n <- tiledb_query_result_buffer_elements(qry, "a")
ndf <- data.frame(rows=rows,a=cola,b=colb)[1:n,]
expect_equal(nrow(ndf), 2)
tiledb_array_close(arr)
rm(qry)

## check a >=5 && b <= 115
qry <- tiledb_query(arr, "READ")
rows <- integer(20)
Expand Down
7 changes: 3 additions & 4 deletions man/tiledb_query_condition_combine.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 17 additions & 0 deletions man/tiledb_query_condition_negate.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions src/RcppExports.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2457,6 +2457,17 @@ BEGIN_RCPP
return rcpp_result_gen;
END_RCPP
}
// libtiledb_query_condition_negate
XPtr<tiledb::QueryCondition> libtiledb_query_condition_negate(XPtr<tiledb::QueryCondition> qc);
RcppExport SEXP _tiledb_libtiledb_query_condition_negate(SEXP qcSEXP) {
BEGIN_RCPP
Rcpp::RObject rcpp_result_gen;
Rcpp::RNGScope rcpp_rngScope_gen;
Rcpp::traits::input_parameter< XPtr<tiledb::QueryCondition> >::type qc(qcSEXP);
rcpp_result_gen = Rcpp::wrap(libtiledb_query_condition_negate(qc));
return rcpp_result_gen;
END_RCPP
}
// libtiledb_query_condition_set_use_enumeration
void libtiledb_query_condition_set_use_enumeration(XPtr<tiledb::Context> ctx, XPtr<tiledb::QueryCondition> cond, bool use_enumeration);
RcppExport SEXP _tiledb_libtiledb_query_condition_set_use_enumeration(SEXP ctxSEXP, SEXP condSEXP, SEXP use_enumerationSEXP) {
Expand Down Expand Up @@ -3957,6 +3968,7 @@ static const R_CallMethodDef CallEntries[] = {
{"_tiledb_libtiledb_query_condition", (DL_FUNC) &_tiledb_libtiledb_query_condition, 1},
{"_tiledb_libtiledb_query_condition_init", (DL_FUNC) &_tiledb_libtiledb_query_condition_init, 5},
{"_tiledb_libtiledb_query_condition_combine", (DL_FUNC) &_tiledb_libtiledb_query_condition_combine, 3},
{"_tiledb_libtiledb_query_condition_negate", (DL_FUNC) &_tiledb_libtiledb_query_condition_negate, 1},
{"_tiledb_libtiledb_query_condition_set_use_enumeration", (DL_FUNC) &_tiledb_libtiledb_query_condition_set_use_enumeration, 3},
{"_tiledb_libtiledb_query_condition_create", (DL_FUNC) &_tiledb_libtiledb_query_condition_create, 4},
{"_tiledb_libtiledb_zip_coords_numeric", (DL_FUNC) &_tiledb_libtiledb_zip_coords_numeric, 2},
Expand Down
10 changes: 10 additions & 0 deletions src/libtiledb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4476,6 +4476,16 @@ libtiledb_query_condition_combine(XPtr<tiledb::QueryCondition> lhs,
return query_cond;
}

// [[Rcpp::export]]
XPtr<tiledb::QueryCondition>
libtiledb_query_condition_negate(XPtr<tiledb::QueryCondition> qc) {
check_xptr_tag<tiledb::QueryCondition>(qc);
tiledb::QueryCondition res = qc->negate();
auto query_cond =
make_xptr<tiledb::QueryCondition>(new tiledb::QueryCondition(res));
return query_cond;
}

// [[Rcpp::export]]
void libtiledb_query_condition_set_use_enumeration(
XPtr<tiledb::Context> ctx, XPtr<tiledb::QueryCondition> cond,
Expand Down
Loading