Skip to content
Merged
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
21 changes: 19 additions & 2 deletions java/testfiles/Cargo.lock

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

8 changes: 8 additions & 0 deletions java/vortex-jni/src/main/java/dev/vortex/api/Expression.java
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,14 @@ interface Visitor<T> {
*/
T visitGetItem(GetItem getItem);

/**
* Visits an is null expression (null check).
*
* @param isNull the is null expression to visit
* @return the result of visiting the is null expression
*/
T visitIsNull(IsNull isNull);

/**
* For expressions that do not have a specific visitor method.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: Copyright the Vortex contributors

package dev.vortex.api.expressions;

import dev.vortex.api.Expression;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
* Represents an IS NULL expression that checks whether values are null.
* This expression returns true for null values and false for non-null values.
*/
public final class IsNull implements Expression {
private final Expression child;

private IsNull(Expression child) {
this.child = child;
}

/**
* Parses an IsNull expression from serialized metadata and child expressions.
* This method is used during deserialization of Vortex expressions.
*
* @param metadata the serialized metadata, must be empty for IsNull expressions
* @param children the child expressions, must contain exactly one element
* @return a new IsNull expression parsed from the provided data
* @throws IllegalArgumentException if the number of children is not exactly one,
* or if metadata is not empty
*/
public static IsNull parse(byte[] metadata, List<Expression> children) {
if (children.size() != 1) {
throw new IllegalArgumentException(
"IsNull expression must have exactly one child, found: " + children.size());
}
if (metadata.length > 0) {
throw new IllegalArgumentException(
"IsNull expression must not have metadata, found: " + metadata.length);
}
return new IsNull(children.get(0));
}

/**
* Creates a new IsNull expression that checks nullity of the given child expression.
*
* @param child the expression to check for null values
* @return a new IsNull expression
*/
public static IsNull of(Expression child) {
return new IsNull(child);
}

@Override
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;
IsNull other = (IsNull) o;
return Objects.equals(child, other.child);
}

@Override
public int hashCode() {
return Objects.hash(child);
}

@Override
public String id() {
return "vortex.is_null";
}

@Override
public List<Expression> children() {
return List.of(child);
}

@Override
public Optional<byte[]> metadata() {
return Optional.of(new byte[] {});
}

@Override
public String toString() {
return "vortex.is_null(" + child + ")";
}

/**
* Returns the child expression that will be checked for null values.
*
* @return the child expression
*/
public Expression getChild() {
return child;
}

@Override
public <T> T accept(Visitor<T> visitor) {
return visitor.visitIsNull(this);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ public static Expression deserialize(ExprProtos.Expr expr) {
return Literal.parse(metadata, children);
case "vortex.not":
return Not.parse(metadata, children);
case "vortex.is_null":
return IsNull.parse(metadata, children);
default:
return new Unknown(expr.getId(), children, expr.getMetadata().toByteArray());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,12 @@ public void testRoundTrip() {
Expression deserialized = Expressions.deserialize(proto);
assertEquals(expression, deserialized);
}

@Test
public void testIsNullRoundTrip() {
Expression expression = IsNull.of(GetItem.of(Root.INSTANCE, "a.b.c"));
ExprProtos.Expr proto = Expressions.serialize(expression);
Expression deserialized = Expressions.deserialize(proto);
assertEquals(expression, deserialized);
}
}
Loading