|
19 | 19 |
|
20 | 20 | #include "iceberg/expression/binder.h" |
21 | 21 |
|
| 22 | +#include "iceberg/util/macros.h" |
| 23 | + |
22 | 24 | namespace iceberg { |
23 | 25 |
|
| 26 | +namespace { |
| 27 | + |
| 28 | +Result<std::optional<bool>> CombineResults(const std::optional<bool>& is_left_bound, |
| 29 | + const std::optional<bool>& is_right_bound) { |
| 30 | + if (is_left_bound.has_value()) { |
| 31 | + ICEBERG_CHECK(!is_right_bound.has_value() || is_left_bound == is_right_bound, |
| 32 | + "Found partially bound expression"); |
| 33 | + return is_left_bound; |
| 34 | + } else { |
| 35 | + return is_right_bound; |
| 36 | + } |
| 37 | +} |
| 38 | + |
| 39 | +} // anonymous namespace |
| 40 | + |
24 | 41 | Binder::Binder(const Schema& schema, bool case_sensitive) |
25 | 42 | : schema_(schema), case_sensitive_(case_sensitive) {} |
26 | 43 |
|
@@ -79,36 +96,47 @@ Result<std::shared_ptr<Expression>> Binder::Aggregate( |
79 | 96 | Result<bool> IsBoundVisitor::IsBound(const std::shared_ptr<Expression>& expr) { |
80 | 97 | ICEBERG_DCHECK(expr != nullptr, "Expression cannot be null"); |
81 | 98 | IsBoundVisitor visitor; |
82 | | - return Visit<bool, IsBoundVisitor>(expr, visitor); |
| 99 | + auto visit_result = Visit<std::optional<bool>, IsBoundVisitor>(expr, visitor); |
| 100 | + ICEBERG_RETURN_UNEXPECTED(visit_result); |
| 101 | + auto result = std::move(visit_result.value()); |
| 102 | + // If the result is null, return true |
| 103 | + return result.value_or(true); |
83 | 104 | } |
84 | 105 |
|
85 | | -Result<bool> IsBoundVisitor::AlwaysTrue() { return true; } |
| 106 | +Result<std::optional<bool>> IsBoundVisitor::AlwaysTrue() { return std::nullopt; } |
86 | 107 |
|
87 | | -Result<bool> IsBoundVisitor::AlwaysFalse() { return true; } |
| 108 | +Result<std::optional<bool>> IsBoundVisitor::AlwaysFalse() { return std::nullopt; } |
88 | 109 |
|
89 | | -Result<bool> IsBoundVisitor::Not(bool child_result) { return child_result; } |
| 110 | +Result<std::optional<bool>> IsBoundVisitor::Not(const std::optional<bool>& child_result) { |
| 111 | + return child_result; |
| 112 | +} |
90 | 113 |
|
91 | | -Result<bool> IsBoundVisitor::And(bool left_result, bool right_result) { |
92 | | - return left_result && right_result; |
| 114 | +Result<std::optional<bool>> IsBoundVisitor::And(const std::optional<bool>& left_result, |
| 115 | + const std::optional<bool>& right_result) { |
| 116 | + return CombineResults(left_result, right_result); |
93 | 117 | } |
94 | 118 |
|
95 | | -Result<bool> IsBoundVisitor::Or(bool left_result, bool right_result) { |
96 | | - return left_result && right_result; |
| 119 | +Result<std::optional<bool>> IsBoundVisitor::Or(const std::optional<bool>& left_result, |
| 120 | + const std::optional<bool>& right_result) { |
| 121 | + return CombineResults(left_result, right_result); |
97 | 122 | } |
98 | 123 |
|
99 | | -Result<bool> IsBoundVisitor::Predicate(const std::shared_ptr<BoundPredicate>& pred) { |
| 124 | +Result<std::optional<bool>> IsBoundVisitor::Predicate( |
| 125 | + const std::shared_ptr<BoundPredicate>& pred) { |
100 | 126 | return true; |
101 | 127 | } |
102 | 128 |
|
103 | | -Result<bool> IsBoundVisitor::Predicate(const std::shared_ptr<UnboundPredicate>& pred) { |
| 129 | +Result<std::optional<bool>> IsBoundVisitor::Predicate( |
| 130 | + const std::shared_ptr<UnboundPredicate>& pred) { |
104 | 131 | return false; |
105 | 132 | } |
106 | 133 |
|
107 | | -Result<bool> IsBoundVisitor::Aggregate(const std::shared_ptr<BoundAggregate>& aggregate) { |
| 134 | +Result<std::optional<bool>> IsBoundVisitor::Aggregate( |
| 135 | + const std::shared_ptr<BoundAggregate>& aggregate) { |
108 | 136 | return true; |
109 | 137 | } |
110 | 138 |
|
111 | | -Result<bool> IsBoundVisitor::Aggregate( |
| 139 | +Result<std::optional<bool>> IsBoundVisitor::Aggregate( |
112 | 140 | const std::shared_ptr<UnboundAggregate>& aggregate) { |
113 | 141 | return false; |
114 | 142 | } |
|
0 commit comments