Skip to content

Commit f98e343

Browse files
committed
Query builder support for NOT CQL syntax
patch by Bret McGuire; reviewed by Bret McGuire and Andy Tolbert for CASSANDRA-19930
1 parent 8ebcd9f commit f98e343

File tree

3 files changed

+124
-1
lines changed

3 files changed

+124
-1
lines changed

query-builder/src/main/java/com/datastax/oss/driver/api/querybuilder/relation/ColumnRelationBuilder.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,28 @@ default ResultT contains(@NonNull Term term) {
4646
default ResultT containsKey(@NonNull Term term) {
4747
return build(" CONTAINS KEY ", term);
4848
}
49+
50+
/**
51+
* Builds a NOT CONTAINS relation for the column.
52+
*
53+
* <p>Note that NOT CONTAINS support is only available in Cassandra 5.1 or later. See <a
54+
* href="https://issues.apache.org/jira/browse/CASSANDRA-18584">CASSANDRA-18584</a> for more
55+
* information.
56+
*/
57+
@NonNull
58+
default ResultT notContains(@NonNull Term term) {
59+
return build(" NOT CONTAINS ", term);
60+
}
61+
62+
/**
63+
* Builds a NOT CONTAINS KEY relation for the column.
64+
*
65+
* <p>Note that NOT CONTAINS KEY support is only available in Cassandra 5.1 or later. See <a
66+
* href="https://issues.apache.org/jira/browse/CASSANDRA-18584">CASSANDRA-18584</a> for more
67+
* information.
68+
*/
69+
@NonNull
70+
default ResultT notContainsKey(@NonNull Term term) {
71+
return build(" NOT CONTAINS KEY ", term);
72+
}
4973
}

query-builder/src/main/java/com/datastax/oss/driver/api/querybuilder/relation/InRelationBuilder.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,38 @@ default ResultT in(@NonNull Term... alternatives) {
5050
return in(Arrays.asList(alternatives));
5151
}
5252

53+
/**
54+
* Builds a NOT IN relation where the whole set of possible values is a bound variable, as in
55+
* {@code NOT IN ?}.
56+
*
57+
* <p>Note that NOT IN support is only available in Cassandra 5.1 or later. See <a
58+
* href="https://issues.apache.org/jira/browse/CASSANDRA-18584">CASSANDRA-18584</a> for more
59+
* information.
60+
*/
61+
@NonNull
62+
default ResultT notIn(@NonNull BindMarker bindMarker) {
63+
return build(" NOT IN ", bindMarker);
64+
}
65+
66+
/**
67+
* Builds an IN relation where the arguments are the possible values, as in {@code IN (term1,
68+
* term2...)}.
69+
*
70+
* <p>Note that NOT IN support is only available in Cassandra 5.1 or later. See <a
71+
* href="https://issues.apache.org/jira/browse/CASSANDRA-18584">CASSANDRA-18584</a> for more
72+
* information.
73+
*/
74+
@NonNull
75+
default ResultT notIn(@NonNull Iterable<Term> alternatives) {
76+
return build(" NOT IN ", QueryBuilder.tuple(alternatives));
77+
}
78+
79+
/** Var-arg equivalent of {@link #notIn(Iterable)} . */
80+
@NonNull
81+
default ResultT notIn(@NonNull Term... alternatives) {
82+
return notIn(Arrays.asList(alternatives));
83+
}
84+
5385
@NonNull
5486
ResultT build(@NonNull String operator, @Nullable Term rightOperand);
5587
}

query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/relation/RelationTest.java

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,12 @@
1919

2020
import static com.datastax.oss.driver.api.querybuilder.Assertions.assertThat;
2121
import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.bindMarker;
22+
import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.literal;
2223
import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.raw;
2324
import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.selectFrom;
2425
import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.tuple;
2526

27+
import org.assertj.core.util.Lists;
2628
import org.junit.Test;
2729

2830
public class RelationTest {
@@ -42,13 +44,78 @@ public void should_generate_is_not_null_relation() {
4244
}
4345

4446
@Test
45-
public void should_generate_in_relation() {
47+
public void should_generate_contains_relation() {
48+
assertThat(selectFrom("foo").all().where(Relation.column("k").contains(literal(1))))
49+
.hasCql("SELECT * FROM foo WHERE k CONTAINS 1");
50+
}
51+
52+
@Test
53+
public void should_generate_contains_key_relation() {
54+
assertThat(selectFrom("foo").all().where(Relation.column("k").containsKey(literal(1))))
55+
.hasCql("SELECT * FROM foo WHERE k CONTAINS KEY 1");
56+
}
57+
58+
@Test
59+
public void should_generate_not_contains_relation() {
60+
assertThat(selectFrom("foo").all().where(Relation.column("k").notContains(literal(1))))
61+
.hasCql("SELECT * FROM foo WHERE k NOT CONTAINS 1");
62+
}
63+
64+
@Test
65+
public void should_generate_not_contains_key_relation() {
66+
assertThat(selectFrom("foo").all().where(Relation.column("k").notContainsKey(literal(1))))
67+
.hasCql("SELECT * FROM foo WHERE k NOT CONTAINS KEY 1");
68+
}
69+
70+
@Test
71+
public void should_generate_in_relation_bind_markers() {
4672
assertThat(selectFrom("foo").all().where(Relation.column("k").in(bindMarker())))
4773
.hasCql("SELECT * FROM foo WHERE k IN ?");
4874
assertThat(selectFrom("foo").all().where(Relation.column("k").in(bindMarker(), bindMarker())))
4975
.hasCql("SELECT * FROM foo WHERE k IN (?,?)");
5076
}
5177

78+
@Test
79+
public void should_generate_in_relation_terms() {
80+
assertThat(
81+
selectFrom("foo")
82+
.all()
83+
.where(
84+
Relation.column("k")
85+
.in(Lists.newArrayList(literal(1), literal(2), literal(3)))))
86+
.hasCql("SELECT * FROM foo WHERE k IN (1,2,3)");
87+
assertThat(
88+
selectFrom("foo")
89+
.all()
90+
.where(Relation.column("k").in(literal(1), literal(2), literal(3))))
91+
.hasCql("SELECT * FROM foo WHERE k IN (1,2,3)");
92+
}
93+
94+
@Test
95+
public void should_generate_not_in_relation_bind_markers() {
96+
assertThat(selectFrom("foo").all().where(Relation.column("k").notIn(bindMarker())))
97+
.hasCql("SELECT * FROM foo WHERE k NOT IN ?");
98+
assertThat(
99+
selectFrom("foo").all().where(Relation.column("k").notIn(bindMarker(), bindMarker())))
100+
.hasCql("SELECT * FROM foo WHERE k NOT IN (?,?)");
101+
}
102+
103+
@Test
104+
public void should_generate_not_in_relation_terms() {
105+
assertThat(
106+
selectFrom("foo")
107+
.all()
108+
.where(
109+
Relation.column("k")
110+
.notIn(Lists.newArrayList(literal(1), literal(2), literal(3)))))
111+
.hasCql("SELECT * FROM foo WHERE k NOT IN (1,2,3)");
112+
assertThat(
113+
selectFrom("foo")
114+
.all()
115+
.where(Relation.column("k").notIn(literal(1), literal(2), literal(3))))
116+
.hasCql("SELECT * FROM foo WHERE k NOT IN (1,2,3)");
117+
}
118+
52119
@Test
53120
public void should_generate_token_relation() {
54121
assertThat(selectFrom("foo").all().where(Relation.token("k1", "k2").isEqualTo(bindMarker("t"))))

0 commit comments

Comments
 (0)