Skip to content

Commit 0b2a35e

Browse files
authored
Add IsNull expression to vortex-jni (#7358)
Add IsNull to vortex-jni bindings --------- Signed-off-by: Robert Kruszewski <github@robertk.io>
1 parent 8974afe commit 0b2a35e

File tree

5 files changed

+136
-2
lines changed

5 files changed

+136
-2
lines changed

java/testfiles/Cargo.lock

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

java/vortex-jni/src/main/java/dev/vortex/api/Expression.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,14 @@ interface Visitor<T> {
8787
*/
8888
T visitGetItem(GetItem getItem);
8989

90+
/**
91+
* Visits an is null expression (null check).
92+
*
93+
* @param isNull the is null expression to visit
94+
* @return the result of visiting the is null expression
95+
*/
96+
T visitIsNull(IsNull isNull);
97+
9098
/**
9199
* For expressions that do not have a specific visitor method.
92100
*/
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
// SPDX-FileCopyrightText: Copyright the Vortex contributors
3+
4+
package dev.vortex.api.expressions;
5+
6+
import dev.vortex.api.Expression;
7+
import java.util.List;
8+
import java.util.Objects;
9+
import java.util.Optional;
10+
11+
/**
12+
* Represents an IS NULL expression that checks whether values are null.
13+
* This expression returns true for null values and false for non-null values.
14+
*/
15+
public final class IsNull implements Expression {
16+
private final Expression child;
17+
18+
private IsNull(Expression child) {
19+
this.child = child;
20+
}
21+
22+
/**
23+
* Parses an IsNull expression from serialized metadata and child expressions.
24+
* This method is used during deserialization of Vortex expressions.
25+
*
26+
* @param metadata the serialized metadata, must be empty for IsNull expressions
27+
* @param children the child expressions, must contain exactly one element
28+
* @return a new IsNull expression parsed from the provided data
29+
* @throws IllegalArgumentException if the number of children is not exactly one,
30+
* or if metadata is not empty
31+
*/
32+
public static IsNull parse(byte[] metadata, List<Expression> children) {
33+
if (children.size() != 1) {
34+
throw new IllegalArgumentException(
35+
"IsNull expression must have exactly one child, found: " + children.size());
36+
}
37+
if (metadata.length > 0) {
38+
throw new IllegalArgumentException(
39+
"IsNull expression must not have metadata, found: " + metadata.length);
40+
}
41+
return new IsNull(children.get(0));
42+
}
43+
44+
/**
45+
* Creates a new IsNull expression that checks nullity of the given child expression.
46+
*
47+
* @param child the expression to check for null values
48+
* @return a new IsNull expression
49+
*/
50+
public static IsNull of(Expression child) {
51+
return new IsNull(child);
52+
}
53+
54+
@Override
55+
public boolean equals(Object o) {
56+
if (o == null || getClass() != o.getClass()) return false;
57+
IsNull other = (IsNull) o;
58+
return Objects.equals(child, other.child);
59+
}
60+
61+
@Override
62+
public int hashCode() {
63+
return Objects.hash(child);
64+
}
65+
66+
@Override
67+
public String id() {
68+
return "vortex.is_null";
69+
}
70+
71+
@Override
72+
public List<Expression> children() {
73+
return List.of(child);
74+
}
75+
76+
@Override
77+
public Optional<byte[]> metadata() {
78+
return Optional.of(new byte[] {});
79+
}
80+
81+
@Override
82+
public String toString() {
83+
return "vortex.is_null(" + child + ")";
84+
}
85+
86+
/**
87+
* Returns the child expression that will be checked for null values.
88+
*
89+
* @return the child expression
90+
*/
91+
public Expression getChild() {
92+
return child;
93+
}
94+
95+
@Override
96+
public <T> T accept(Visitor<T> visitor) {
97+
return visitor.visitIsNull(this);
98+
}
99+
}

java/vortex-jni/src/main/java/dev/vortex/api/proto/Expressions.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ public static Expression deserialize(ExprProtos.Expr expr) {
5656
return Literal.parse(metadata, children);
5757
case "vortex.not":
5858
return Not.parse(metadata, children);
59+
case "vortex.is_null":
60+
return IsNull.parse(metadata, children);
5961
default:
6062
return new Unknown(expr.getId(), children, expr.getMetadata().toByteArray());
6163
}

java/vortex-jni/src/test/java/dev/vortex/api/expressions/proto/TestExpressionProtos.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,12 @@ public void testRoundTrip() {
2222
Expression deserialized = Expressions.deserialize(proto);
2323
assertEquals(expression, deserialized);
2424
}
25+
26+
@Test
27+
public void testIsNullRoundTrip() {
28+
Expression expression = IsNull.of(GetItem.of(Root.INSTANCE, "a.b.c"));
29+
ExprProtos.Expr proto = Expressions.serialize(expression);
30+
Expression deserialized = Expressions.deserialize(proto);
31+
assertEquals(expression, deserialized);
32+
}
2533
}

0 commit comments

Comments
 (0)