2020#include " iceberg/expression/predicate.h"
2121
2222#include < algorithm>
23+ #include < cmath>
2324#include < format>
2425
25- #include " iceberg/exception.h"
2626#include " iceberg/expression/expressions.h"
2727#include " iceberg/expression/literal.h"
2828#include " iceberg/result.h"
@@ -143,6 +143,26 @@ bool IsFloatingType(TypeId type) {
143143 return type == TypeId::kFloat || type == TypeId::kDouble ;
144144}
145145
146+ bool IsNan (const Literal& literal) {
147+ const auto & value = literal.value ();
148+ if (std::holds_alternative<float >(value)) {
149+ return std::isnan (std::get<float >(value));
150+ } else if (std::holds_alternative<double >(value)) {
151+ return std::isnan (std::get<double >(value));
152+ }
153+ return false ;
154+ }
155+
156+ bool StartsWith (const Literal& lhs, const Literal& rhs) {
157+ const auto & lhs_value = lhs.value ();
158+ const auto & rhs_value = rhs.value ();
159+ if (std::holds_alternative<std::string>(lhs_value) &&
160+ std::holds_alternative<std::string>(rhs_value)) {
161+ return std::get<std::string>(lhs_value).starts_with (std::get<std::string>(rhs_value));
162+ }
163+ return false ;
164+ }
165+
146166} // namespace
147167
148168template <typename B>
@@ -287,10 +307,10 @@ BoundPredicate::BoundPredicate(Expression::Operation op, std::shared_ptr<BoundTe
287307
288308BoundPredicate::~BoundPredicate () = default ;
289309
290- Result<Literal::Value > BoundPredicate::Evaluate (const StructLike& data) const {
310+ Result<Literal> BoundPredicate::Evaluate (const StructLike& data) const {
291311 ICEBERG_ASSIGN_OR_RAISE (auto eval_result, term_->Evaluate (data));
292312 ICEBERG_ASSIGN_OR_RAISE (auto test_result, Test (eval_result));
293- return Literal::Value{ test_result} ;
313+ return Literal::Boolean ( test_result) ;
294314}
295315
296316// BoundUnaryPredicate implementation
@@ -300,8 +320,19 @@ BoundUnaryPredicate::BoundUnaryPredicate(Expression::Operation op,
300320
301321BoundUnaryPredicate::~BoundUnaryPredicate () = default ;
302322
303- Result<bool > BoundUnaryPredicate::Test (const Literal::Value& value) const {
304- return NotImplemented (" BoundUnaryPredicate::Test not implemented" );
323+ Result<bool > BoundUnaryPredicate::Test (const Literal& literal) const {
324+ switch (op ()) {
325+ case Expression::Operation::kIsNull :
326+ return literal.IsNull ();
327+ case Expression::Operation::kNotNull :
328+ return !literal.IsNull ();
329+ case Expression::Operation::kIsNan :
330+ return IsNan (literal);
331+ case Expression::Operation::kNotNan :
332+ return !IsNan (literal);
333+ default :
334+ return InvalidExpression (" Invalid operation for BoundUnaryPredicate: {}" , op ());
335+ }
305336}
306337
307338Result<std::shared_ptr<Expression>> BoundUnaryPredicate::Negate () const {
@@ -345,8 +376,27 @@ BoundLiteralPredicate::BoundLiteralPredicate(Expression::Operation op,
345376
346377BoundLiteralPredicate::~BoundLiteralPredicate () = default ;
347378
348- Result<bool > BoundLiteralPredicate::Test (const Literal::Value& value) const {
349- return NotImplemented (" BoundLiteralPredicate::Test not implemented" );
379+ Result<bool > BoundLiteralPredicate::Test (const Literal& value) const {
380+ switch (op ()) {
381+ case Expression::Operation::kLt :
382+ return value < literal_;
383+ case Expression::Operation::kLtEq :
384+ return value <= literal_;
385+ case Expression::Operation::kGt :
386+ return value > literal_;
387+ case Expression::Operation::kGtEq :
388+ return value >= literal_;
389+ case Expression::Operation::kEq :
390+ return value == literal_;
391+ case Expression::Operation::kNotEq :
392+ return value != literal_;
393+ case Expression::Operation::kStartsWith :
394+ return StartsWith (value, literal_);
395+ case Expression::Operation::kNotStartsWith :
396+ return !StartsWith (value, literal_);
397+ default :
398+ return InvalidExpression (" Invalid operation for BoundLiteralPredicate: {}" , op ());
399+ }
350400}
351401
352402Result<std::shared_ptr<Expression>> BoundLiteralPredicate::Negate () const {
@@ -453,8 +503,15 @@ BoundSetPredicate::BoundSetPredicate(Expression::Operation op,
453503
454504BoundSetPredicate::~BoundSetPredicate () = default ;
455505
456- Result<bool > BoundSetPredicate::Test (const Literal::Value& value) const {
457- return NotImplemented (" BoundSetPredicate::Test not implemented" );
506+ Result<bool > BoundSetPredicate::Test (const Literal& value) const {
507+ switch (op ()) {
508+ case Expression::Operation::kIn :
509+ return value_set_.contains (value);
510+ case Expression::Operation::kNotIn :
511+ return !value_set_.contains (value);
512+ default :
513+ return InvalidExpression (" Invalid operation for BoundSetPredicate: {}" , op ());
514+ }
458515}
459516
460517Result<std::shared_ptr<Expression>> BoundSetPredicate::Negate () const {
0 commit comments