Skip to content

Commit 7b7d954

Browse files
committed
Add tiledb_query_condition_negate wrapper to R API
1 parent e48e77e commit 7b7d954

File tree

10 files changed

+101
-11
lines changed

10 files changed

+101
-11
lines changed

DESCRIPTION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Package: tiledb
22
Type: Package
3-
Version: 0.31.1
3+
Version: 0.31.1.1
44
Title: Modern Database Engine for Complex Data Based on Multi-Dimensional Arrays
55
Authors@R: c(
66
person("TileDB, Inc.", role = c("aut", "cph")),

NAMESPACE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,7 @@ export(tiledb_query_condition)
251251
export(tiledb_query_condition_combine)
252252
export(tiledb_query_condition_create)
253253
export(tiledb_query_condition_init)
254+
export(tiledb_query_condition_negate)
254255
export(tiledb_query_condition_set_use_enumeration)
255256
export(tiledb_query_create_buffer_ptr)
256257
export(tiledb_query_create_buffer_ptr_char)

NEWS.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# tiledb 0.31.2
2+
3+
* 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)
4+
15
# tiledb 0.31.1
26

37
* Allow `parse_query_condition()` to work on dimensions when an array is passed

R/QueryCondition.R

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -86,12 +86,11 @@ tiledb_query_condition_init <- function(attr, value, dtype, op, qc = tiledb_quer
8686

8787
#' Combine two 'tiledb_query_condition' objects
8888
#'
89-
#' Combines two query condition object using a relatiional operator. Support for operator
90-
#' 'AND' is generally available, the 'OR' operator is available if TileDB 2.10 or newer is
91-
#' used.
89+
#' Combines two query condition objects using a relational operator. Support for operator
90+
#' 'AND' is generally available. The 'OR' operator is available in TileDB 2.10 and later.
9291
#' @param lhs A 'tiledb_query_condition' object on the left-hand side of the relation
9392
#' @param rhs A 'tiledb_query_condition' object on the left-hand side of the relation
94-
#' @param op A character value with then relation, this must be one of 'AND', 'OR' or 'NOT'.
93+
#' @param op A character value with then relation, this must be one of 'AND' or 'OR'.
9594
#' @return The combined 'tiledb_query_condition' object
9695
#' @export
9796
tiledb_query_condition_combine <- function(lhs, rhs, op) {
@@ -100,13 +99,29 @@ tiledb_query_condition_combine <- function(lhs, rhs, op) {
10099
"Argument 'rhs' must be a query condition object" = is(rhs, "tiledb_query_condition"),
101100
"Argument 'op' must be a character" = is.character(op)
102101
)
103-
op <- match.arg(op, c("AND", "OR", "NOT"))
102+
op <- match.arg(op, c("AND", "OR"))
104103
qc <- tiledb_query_condition()
105104
qc@ptr <- libtiledb_query_condition_combine(lhs@ptr, rhs@ptr, op)
106105
qc@init <- TRUE
107106
invisible(qc)
108107
}
109108

109+
#' Negate a 'tiledb_query_condition' object
110+
#'
111+
#' Takes a query condition object and negates it, similar to the '!' operator.
112+
#' @param qc A 'tiledb_query_condition' object to negate
113+
#' @return The negated 'tiledb_query_condition' object
114+
#' @export
115+
tiledb_query_condition_negate <- function(qc) {
116+
stopifnot(
117+
"Argument 'qc' must be a query condition object" = is(qc, "tiledb_query_condition")
118+
)
119+
res <- tiledb_query_condition()
120+
res@ptr <- libtiledb_query_condition_negate(qc@ptr)
121+
res@init <- TRUE
122+
invisible(res)
123+
}
124+
110125
#' Create a 'tiledb_query_condition' object from an expression
111126
#'
112127
#' The grammar for query conditions is at present constraint to eight operators (\code{">"},
@@ -150,7 +165,8 @@ parse_query_condition <- function(expr, ta = NULL, debug = FALSE, strict = TRUE,
150165
if (.hasArray && length(ta@sil) == 0) ta@sil <- .fill_schema_info_list(ta@uri)
151166
`%!in%` <- Negate(`%in%`)
152167
.isComparisonOperator <- function(x) tolower(as.character(x)) %in% c(">", ">=", "<", "<=", "==", "!=", "%in%", "%nin%")
153-
.isBooleanOperator <- function(x) as.character(x) %in% c("&&", "||", "!", "&", "|")
168+
.isBooleanOperator <- function(x) as.character(x) %in% c("&&", "||", "&", "|")
169+
.isNegationOperator <- function(x) as.character(x) == "!"
154170
.isAscii <- function(x) grepl("^[[:alnum:]_]+$", x)
155171
.isInteger <- function(x) grepl("^[[:digit:]]+$", as.character(x))
156172
.isDouble <- function(x) grepl("^[[:digit:]\\.]+$", as.character(x)) && length(grepRaw(".", as.character(x), fixed = TRUE, all = TRUE)) == 1
@@ -224,6 +240,12 @@ parse_query_condition <- function(expr, ta = NULL, debug = FALSE, strict = TRUE,
224240
.makeExpr(x[[3]]),
225241
.mapBoolToCharacter(as.character(x[1]))
226242
)
243+
} else if (.isNegationOperator(x[1])) {
244+
if (debug) {
245+
cat(" ![", as.character(x[2]), "]")
246+
}
247+
.makeExpr(x[[2]], debug = debug)
248+
tiledb_query_condition_negate(.makeExpr(x[[2]]))
227249
} else if (.isInOperator(x[1])) {
228250
if (debug) {
229251
cat("in: [", as.character(x[2]), "]",

R/RcppExports.R

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -825,6 +825,10 @@ libtiledb_query_condition_combine <- function(lhs, rhs, str) {
825825
.Call(`_tiledb_libtiledb_query_condition_combine`, lhs, rhs, str)
826826
}
827827

828+
libtiledb_query_condition_negate <- function(qc) {
829+
.Call(`_tiledb_libtiledb_query_condition_negate`, qc)
830+
}
831+
828832
libtiledb_query_condition_set_use_enumeration <- function(ctx, cond, use_enumeration) {
829833
invisible(.Call(`_tiledb_libtiledb_query_condition_set_use_enumeration`, ctx, cond, use_enumeration))
830834
}

inst/tinytest/test_querycondition.R

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,27 @@ expect_equal(nrow(ndf), 18)
7575
tiledb_array_close(arr)
7676
rm(qry)
7777

78+
## check the negative of the previous condition
79+
qry <- tiledb_query(arr, "READ")
80+
rows <- integer(20)
81+
cola <- integer(20)
82+
colb <- numeric(20)
83+
tiledb_query_set_buffer(qry, "__tiledb_rows", rows)
84+
tiledb_query_set_buffer(qry, "a", cola)
85+
tiledb_query_set_buffer(qry, "b", colb)
86+
lhs <- tiledb_query_condition_init("a", 2L, "INT32", "NE")
87+
rhs <- tiledb_query_condition_init("a", 12L, "INT32", "NE")
88+
qc <- tiledb_query_condition_combine(lhs, rhs, "AND")
89+
qc_inv <- tiledb_query_condition_negate(qc)
90+
qry <- tiledb_query_set_condition(qry, qc_inv)
91+
tiledb_query_submit(qry)
92+
tiledb_query_finalize(qry)
93+
n <- tiledb_query_result_buffer_elements(qry, "a")
94+
ndf <- data.frame(rows=rows,a=cola,b=colb)[1:n,]
95+
expect_equal(nrow(ndf), 2)
96+
tiledb_array_close(arr)
97+
rm(qry)
98+
7899
## check a >=5 && b <= 115
79100
qry <- tiledb_query(arr, "READ")
80101
rows <- integer(20)

man/tiledb_query_condition_combine.Rd

Lines changed: 3 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/tiledb_query_condition_negate.Rd

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/RcppExports.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2457,6 +2457,17 @@ BEGIN_RCPP
24572457
return rcpp_result_gen;
24582458
END_RCPP
24592459
}
2460+
// libtiledb_query_condition_negate
2461+
XPtr<tiledb::QueryCondition> libtiledb_query_condition_negate(XPtr<tiledb::QueryCondition> qc);
2462+
RcppExport SEXP _tiledb_libtiledb_query_condition_negate(SEXP qcSEXP) {
2463+
BEGIN_RCPP
2464+
Rcpp::RObject rcpp_result_gen;
2465+
Rcpp::RNGScope rcpp_rngScope_gen;
2466+
Rcpp::traits::input_parameter< XPtr<tiledb::QueryCondition> >::type qc(qcSEXP);
2467+
rcpp_result_gen = Rcpp::wrap(libtiledb_query_condition_negate(qc));
2468+
return rcpp_result_gen;
2469+
END_RCPP
2470+
}
24602471
// libtiledb_query_condition_set_use_enumeration
24612472
void libtiledb_query_condition_set_use_enumeration(XPtr<tiledb::Context> ctx, XPtr<tiledb::QueryCondition> cond, bool use_enumeration);
24622473
RcppExport SEXP _tiledb_libtiledb_query_condition_set_use_enumeration(SEXP ctxSEXP, SEXP condSEXP, SEXP use_enumerationSEXP) {
@@ -3957,6 +3968,7 @@ static const R_CallMethodDef CallEntries[] = {
39573968
{"_tiledb_libtiledb_query_condition", (DL_FUNC) &_tiledb_libtiledb_query_condition, 1},
39583969
{"_tiledb_libtiledb_query_condition_init", (DL_FUNC) &_tiledb_libtiledb_query_condition_init, 5},
39593970
{"_tiledb_libtiledb_query_condition_combine", (DL_FUNC) &_tiledb_libtiledb_query_condition_combine, 3},
3971+
{"_tiledb_libtiledb_query_condition_negate", (DL_FUNC) &_tiledb_libtiledb_query_condition_negate, 1},
39603972
{"_tiledb_libtiledb_query_condition_set_use_enumeration", (DL_FUNC) &_tiledb_libtiledb_query_condition_set_use_enumeration, 3},
39613973
{"_tiledb_libtiledb_query_condition_create", (DL_FUNC) &_tiledb_libtiledb_query_condition_create, 4},
39623974
{"_tiledb_libtiledb_zip_coords_numeric", (DL_FUNC) &_tiledb_libtiledb_zip_coords_numeric, 2},

src/libtiledb.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4476,6 +4476,16 @@ libtiledb_query_condition_combine(XPtr<tiledb::QueryCondition> lhs,
44764476
return query_cond;
44774477
}
44784478

4479+
// [[Rcpp::export]]
4480+
XPtr<tiledb::QueryCondition>
4481+
libtiledb_query_condition_negate(XPtr<tiledb::QueryCondition> qc) {
4482+
check_xptr_tag<tiledb::QueryCondition>(qc);
4483+
tiledb::QueryCondition res = qc->negate();
4484+
auto query_cond =
4485+
make_xptr<tiledb::QueryCondition>(new tiledb::QueryCondition(res));
4486+
return query_cond;
4487+
}
4488+
44794489
// [[Rcpp::export]]
44804490
void libtiledb_query_condition_set_use_enumeration(
44814491
XPtr<tiledb::Context> ctx, XPtr<tiledb::QueryCondition> cond,

0 commit comments

Comments
 (0)