Skip to content
Merged
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
49 changes: 49 additions & 0 deletions core/src/main/java/io/substrait/relation/Join.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,60 @@
import java.util.stream.Stream;
import org.immutables.value.Value;

/** A binary join relation combining a left and right input according to a {@link JoinType}. */
@Value.Immutable
public abstract class Join extends BiRel implements HasExtension {

/**
* Returns the join condition evaluated against pairs of left and right rows, if any.
*
* @return the optional join condition
*/
public abstract Optional<Expression> getCondition();

/**
* Returns the filter applied to the join output after the join is performed, if any.
*
* @return the optional post-join filter
*/
public abstract Optional<Expression> getPostJoinFilter();

/**
* Returns the type of join to perform.
*
* @return the join type
*/
public abstract JoinType getJoinType();

/** The kinds of join supported by a {@link Join} relation. */
public enum JoinType {
/** Unspecified or unknown join type. */
UNKNOWN(JoinRel.JoinType.JOIN_TYPE_UNSPECIFIED),
/** Inner join: only matching left/right row pairs. */
INNER(JoinRel.JoinType.JOIN_TYPE_INNER),
/** Full outer join: all rows from both sides, with non-matches padded with nulls. */
OUTER(JoinRel.JoinType.JOIN_TYPE_OUTER),
/** Left outer join: all left rows, with non-matching right columns padded with nulls. */
LEFT(JoinRel.JoinType.JOIN_TYPE_LEFT),
/** Right outer join: all right rows, with non-matching left columns padded with nulls. */
RIGHT(JoinRel.JoinType.JOIN_TYPE_RIGHT),
/** Left semi join: left rows that have at least one match on the right. */
LEFT_SEMI(JoinRel.JoinType.JOIN_TYPE_LEFT_SEMI),
/** Left anti join: left rows that have no match on the right. */
LEFT_ANTI(JoinRel.JoinType.JOIN_TYPE_LEFT_ANTI),
/** Left single join: each left row paired with at most one matching right row. */
LEFT_SINGLE(JoinRel.JoinType.JOIN_TYPE_LEFT_SINGLE),
/** Right semi join: right rows that have at least one match on the left. */
RIGHT_SEMI(JoinRel.JoinType.JOIN_TYPE_RIGHT_SEMI),
/** Right anti join: right rows that have no match on the left. */
RIGHT_ANTI(JoinRel.JoinType.JOIN_TYPE_RIGHT_ANTI),
/** Right single join: each right row paired with at most one matching left row. */
RIGHT_SINGLE(JoinRel.JoinType.JOIN_TYPE_RIGHT_SINGLE),
/** Left mark join: left rows with an appended boolean column marking whether a match exists. */
LEFT_MARK(JoinRel.JoinType.JOIN_TYPE_LEFT_MARK),
/**
* Right mark join: right rows with an appended boolean column marking whether a match exists.
*/
RIGHT_MARK(JoinRel.JoinType.JOIN_TYPE_RIGHT_MARK),
// deprecated values last to not get them looked up first in fromProto()
/** use {@link #LEFT_SEMI} instead */
Expand All @@ -46,10 +78,22 @@ public enum JoinType {
this.proto = proto;
}

/**
* Returns the protobuf representation of this join type.
*
* @return the proto join type
*/
public JoinRel.JoinType toProto() {
return proto;
}

/**
* Returns the {@link JoinType} matching the given protobuf join type.
*
* @param proto the proto join type
* @return the matching join type
* @throws IllegalArgumentException if the type is not recognized
*/
public static JoinType fromProto(JoinRel.JoinType proto) {
for (JoinType v : values()) {
if (v.proto == proto) {
Expand Down Expand Up @@ -124,6 +168,11 @@ public <O, C extends VisitationContext, E extends Exception> O accept(
return visitor.visit(this, context);
}

/**
* Creates a builder for {@link Join}.
*
* @return a new builder
*/
public static ImmutableJoin.Builder builder() {
return ImmutableJoin.builder();
}
Expand Down
Loading