Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(exprs): Adding BooleanExpressions and Predicates #91

Merged
merged 2 commits into from
Jun 25, 2024

Conversation

zeroshade
Copy link
Member

Building on #76, this PR implements the interfaces and basic implementations of BooleanExpressions, bound and unbound predicates, and a series of wrapper functions for convenience. It also adds tests for these structs. Where possible, type safety is attempted by using generics to try to enforce types and to reduce the need for type switching in subsequent PRs.

@zeroshade
Copy link
Member Author

CC @Fokko @wolfeidau @nastra

Copy link
Contributor

@Fokko Fokko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zeroshade First of all, sorry for the late review. This looks good! Not many comments since it is mostly a copy of PyIceberg :)

Can you go over the small nits and resolve the conflicts so we can get this in? Thanks! 🙌

Comment on lines +45 to +50
OpLT // LessThan
OpLTEQ // LessThanEqual
OpGT // GreaterThan
OpGTEQ // GreaterThanEqual
OpEQ // Equal
OpNEQ // NotEqual
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WDYT? For consistency. Sometimes we abbreviate with NEQ. maybe it is good to be more explicit in all of them:

Suggested change
OpLT // LessThan
OpLTEQ // LessThanEqual
OpGT // GreaterThan
OpGTEQ // GreaterThanEqual
OpEQ // Equal
OpNEQ // NotEqual
OpLessThan // LessThan
OpLessThanOrEqual // LessThanEqual
OpGreaterThan // GreaterThan
OpGreaterThanOrEqual // GreaterThanEqual
OpEqualTo // Equal
OpNotEqualTo // NotEqual

This also removes the need for the comments :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm now seeing predicates.go, if this is just internal, feel free to ignore the comment above.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the comment lines on those are for use with stringer to auto-generate the String() method for the enum values. By adding the -linecomment option it uses the comment as the string that gets returned instead of just creating a string from the value. e.g. OpLessThan.String() would return "OpLessThan", but by using -linecomment and adding // LessThan to it, it returns "LessThan".

Does that make sense?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that makes sense. Thanks for the explanation 👍

Comment on lines +241 to +242
return (a.left.Equals(rhs.left) && a.right.Equals(rhs.right)) ||
(a.left.Equals(rhs.right) && a.right.Equals(rhs.left))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with this, but I don't think it is exhaustive. For example:

NewAnd(a, b, c, d) becomes AndExpr(a, AndExpr(b, AndExpr(c, d)))

This would yield False:

AndExpr(a, AndExpr(b, AndExpr(c, d))).equals(AndExpr(d, AndExpr(b, AndExpr(c, a))))

But the expression is equivalent

}

func (a AndExpr) Negate() BooleanExpression {
return NewOr(a.left.Negate(), a.right.Negate())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Morgan's law :)

case T:
return Optional[T]{Valid: true, Val: v}
}
panic("unexpected type returned for bound ref")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to include the unexpected type in the error message?

}

if (ul.op == OpStartsWith || ul.op == OpNotStartsWith) &&
!bound.Type().Equals(PrimitiveTypes.String) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Not)StartsWith can also be applied to Binary types

@Fokko Fokko merged commit 704a6e7 into apache:main Jun 25, 2024
5 checks passed
@Fokko
Copy link
Contributor

Fokko commented Jun 25, 2024

Sorry for the late review, thanks for working on this @zeroshade 🙌

@zeroshade zeroshade deleted the expr-definitions branch June 26, 2024 14:56
@zeroshade zeroshade restored the expr-definitions branch June 26, 2024 14:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants