31#include "iceberg/expression/literal.h"
34#include "iceberg/iceberg_export.h"
35#include "iceberg/result.h"
37#include "iceberg/util/macros.h"
50 using ParamType = std::conditional_t<std::is_fundamental_v<R>, R,
const R&>;
63 virtual Result<R>
Not(ParamType child_result) = 0;
68 virtual Result<R>
And(ParamType left_result, ParamType right_result) = 0;
73 virtual Result<R>
Or(ParamType left_result, ParamType right_result) = 0;
77 virtual Result<R>
Predicate(
const std::shared_ptr<BoundPredicate>& pred) = 0;
81 virtual Result<R>
Predicate(
const std::shared_ptr<UnboundPredicate>& pred) = 0;
85 virtual Result<R>
Aggregate(
const std::shared_ptr<BoundAggregate>& aggregate) {
86 ICEBERG_DCHECK(aggregate !=
nullptr,
"Bound aggregate cannot be null");
87 return NotSupported(
"Visitor {} does not support bound aggregate",
88 typeid(*this).name());
93 virtual Result<R>
Aggregate(
const std::shared_ptr<UnboundAggregate>& aggregate) {
94 ICEBERG_DCHECK(aggregate !=
nullptr,
"Unbound aggregate cannot be null");
95 return NotSupported(
"Visitor {} does not support unbound aggregate",
96 typeid(*this).name());
112 virtual Result<R>
IsNull(
const std::shared_ptr<Bound>& expr) = 0;
116 virtual Result<R>
NotNull(
const std::shared_ptr<Bound>& expr) = 0;
120 virtual Result<R>
IsNaN(
const std::shared_ptr<Bound>& expr) {
121 return NotSupported(
"IsNaN operation is not supported by this visitor");
126 virtual Result<R>
NotNaN(
const std::shared_ptr<Bound>& expr) {
127 return NotSupported(
"NotNaN operation is not supported by this visitor");
133 virtual Result<R>
Lt(
const std::shared_ptr<Bound>& expr,
const Literal& lit) = 0;
138 virtual Result<R>
LtEq(
const std::shared_ptr<Bound>& expr,
const Literal& lit) = 0;
143 virtual Result<R>
Gt(
const std::shared_ptr<Bound>& expr,
const Literal& lit) = 0;
148 virtual Result<R>
GtEq(
const std::shared_ptr<Bound>& expr,
const Literal& lit) = 0;
153 virtual Result<R>
Eq(
const std::shared_ptr<Bound>& expr,
const Literal& lit) = 0;
158 virtual Result<R>
NotEq(
const std::shared_ptr<Bound>& expr,
const Literal& lit) = 0;
163 virtual Result<R>
StartsWith([[maybe_unused]]
const std::shared_ptr<Bound>& expr,
164 [[maybe_unused]]
const Literal& lit) {
165 return NotSupported(
"StartsWith operation is not supported by this visitor");
171 virtual Result<R>
NotStartsWith([[maybe_unused]]
const std::shared_ptr<Bound>& expr,
172 [[maybe_unused]]
const Literal& lit) {
173 return NotSupported(
"NotStartsWith operation is not supported by this visitor");
179 virtual Result<R>
In(
180 [[maybe_unused]]
const std::shared_ptr<Bound>& expr,
181 [[maybe_unused]]
const BoundSetPredicate::LiteralSet& literal_set) {
182 return NotSupported(
"In operation is not supported by this visitor");
189 [[maybe_unused]]
const std::shared_ptr<Bound>& expr,
190 [[maybe_unused]]
const BoundSetPredicate::LiteralSet& literal_set) {
191 return NotSupported(
"NotIn operation is not supported by this visitor");
200 Result<R>
Predicate(
const std::shared_ptr<BoundPredicate>& pred)
override {
201 ICEBERG_DCHECK(pred !=
nullptr,
"BoundPredicate cannot be null");
203 switch (pred->kind()) {
204 case BoundPredicate::Kind::kUnary: {
205 switch (pred->op()) {
206 case Expression::Operation::kIsNull:
207 return IsNull(pred->term());
208 case Expression::Operation::kNotNull:
209 return NotNull(pred->term());
210 case Expression::Operation::kIsNan:
211 return IsNaN(pred->term());
212 case Expression::Operation::kNotNan:
213 return NotNaN(pred->term());
215 return InvalidExpression(
"Invalid operation for BoundUnaryPredicate: {}",
216 ToString(pred->op()));
219 case BoundPredicate::Kind::kLiteral: {
220 const auto& literal_pred =
221 internal::checked_cast<const BoundLiteralPredicate&>(*pred);
222 switch (pred->op()) {
223 case Expression::Operation::kLt:
224 return Lt(pred->term(), literal_pred.literal());
225 case Expression::Operation::kLtEq:
226 return LtEq(pred->term(), literal_pred.literal());
227 case Expression::Operation::kGt:
228 return Gt(pred->term(), literal_pred.literal());
229 case Expression::Operation::kGtEq:
230 return GtEq(pred->term(), literal_pred.literal());
231 case Expression::Operation::kEq:
232 return Eq(pred->term(), literal_pred.literal());
233 case Expression::Operation::kNotEq:
234 return NotEq(pred->term(), literal_pred.literal());
235 case Expression::Operation::kStartsWith:
236 return StartsWith(pred->term(), literal_pred.literal());
237 case Expression::Operation::kNotStartsWith:
238 return NotStartsWith(pred->term(), literal_pred.literal());
240 return InvalidExpression(
"Invalid operation for BoundLiteralPredicate: {}",
241 ToString(pred->op()));
244 case BoundPredicate::Kind::kSet: {
245 const auto& set_pred = internal::checked_cast<const BoundSetPredicate&>(*pred);
246 switch (pred->op()) {
247 case Expression::Operation::kIn:
248 return In(pred->term(), set_pred.literal_set());
249 case Expression::Operation::kNotIn:
250 return NotIn(pred->term(), set_pred.literal_set());
252 return InvalidExpression(
"Invalid operation for BoundSetPredicate: {}",
253 ToString(pred->op()));
258 return InvalidExpression(
"Unsupported bound predicate: {}", pred->ToString());
264 Result<R>
Predicate(
const std::shared_ptr<UnboundPredicate>& pred)
override {
265 ICEBERG_DCHECK(pred !=
nullptr,
"UnboundPredicate cannot be null");
266 return NotSupported(
"Not a bound predicate: {}", pred->ToString());
281template <
typename R,
typename V>
282 requires std::derived_from<V, ExpressionVisitor<R>>
283Result<R>
Visit(
const std::shared_ptr<Expression>& expr, V& visitor) {
284 ICEBERG_DCHECK(expr !=
nullptr,
"Expression cannot be null");
286 if (expr->is_bound_predicate()) {
287 return visitor.Predicate(std::dynamic_pointer_cast<BoundPredicate>(expr));
290 if (expr->is_unbound_predicate()) {
291 return visitor.Predicate(std::dynamic_pointer_cast<UnboundPredicate>(expr));
294 if (expr->is_bound_aggregate()) {
295 return visitor.Aggregate(std::dynamic_pointer_cast<BoundAggregate>(expr));
298 if (expr->is_unbound_aggregate()) {
299 return visitor.Aggregate(std::dynamic_pointer_cast<UnboundAggregate>(expr));
302 switch (expr->op()) {
303 case Expression::Operation::kTrue:
304 return visitor.AlwaysTrue();
305 case Expression::Operation::kFalse:
306 return visitor.AlwaysFalse();
307 case Expression::Operation::kNot: {
308 const auto& not_expr = internal::checked_pointer_cast<Not>(expr);
309 ICEBERG_ASSIGN_OR_RAISE(
auto child_result,
310 (Visit<R, V>(not_expr->child(), visitor)));
311 return visitor.Not(std::move(child_result));
313 case Expression::Operation::kAnd: {
314 const auto& and_expr = internal::checked_pointer_cast<And>(expr);
315 ICEBERG_ASSIGN_OR_RAISE(
auto left_result, (Visit<R, V>(and_expr->left(), visitor)));
316 ICEBERG_ASSIGN_OR_RAISE(
auto right_result,
317 (Visit<R, V>(and_expr->right(), visitor)));
318 return visitor.And(std::move(left_result), std::move(right_result));
320 case Expression::Operation::kOr: {
321 const auto& or_expr = internal::checked_pointer_cast<Or>(expr);
322 ICEBERG_ASSIGN_OR_RAISE(
auto left_result, (Visit<R, V>(or_expr->left(), visitor)));
323 ICEBERG_ASSIGN_OR_RAISE(
auto right_result,
324 (Visit<R, V>(or_expr->right(), visitor)));
325 return visitor.Or(std::move(left_result), std::move(right_result));
328 return InvalidExpression(
"Unknown expression operation: {}", expr->ToString());
Checked cast functions for dynamic_cast and static_cast. Adapted from Apache Arrow https://github....
Visitor for bound expressions.
Definition expression_visitor.h:106
virtual Result< R > Gt(const std::shared_ptr< Bound > &expr, const Literal &lit)=0
Visit a greater-than bound expression.
virtual Result< R > Lt(const std::shared_ptr< Bound > &expr, const Literal &lit)=0
Visit a less-than bound expression.
virtual Result< R > IsNull(const std::shared_ptr< Bound > &expr)=0
Visit an IS_NULL bound expression.
Result< R > Predicate(const std::shared_ptr< UnboundPredicate > &pred) override
Visit an unbound predicate.
Definition expression_visitor.h:264
virtual Result< R > NotStartsWith(const std::shared_ptr< Bound > &expr, const Literal &lit)
Visit a not-starts-with bound expression.
Definition expression_visitor.h:171
virtual Result< R > LtEq(const std::shared_ptr< Bound > &expr, const Literal &lit)=0
Visit a less-than-or-equal bound expression.
virtual Result< R > In(const std::shared_ptr< Bound > &expr, const BoundSetPredicate::LiteralSet &literal_set)
Visit an IN set bound expression.
Definition expression_visitor.h:179
virtual Result< R > NotIn(const std::shared_ptr< Bound > &expr, const BoundSetPredicate::LiteralSet &literal_set)
Visit a NOT_IN set bound expression.
Definition expression_visitor.h:188
virtual Result< R > GtEq(const std::shared_ptr< Bound > &expr, const Literal &lit)=0
Visit a greater-than-or-equal bound expression.
virtual Result< R > NotNull(const std::shared_ptr< Bound > &expr)=0
Visit a NOT_NULL bound expression.
virtual Result< R > NotEq(const std::shared_ptr< Bound > &expr, const Literal &lit)=0
Visit a not-equal bound expression.
Result< R > Predicate(const std::shared_ptr< BoundPredicate > &pred) override
Visit a bound predicate.
Definition expression_visitor.h:200
virtual Result< R > Eq(const std::shared_ptr< Bound > &expr, const Literal &lit)=0
Visit an equality bound expression.
virtual Result< R > IsNaN(const std::shared_ptr< Bound > &expr)
Visit an IS_NAN bound expression.
Definition expression_visitor.h:120
virtual Result< R > NotNaN(const std::shared_ptr< Bound > &expr)
Visit a NOT_NAN bound expression.
Definition expression_visitor.h:126
virtual Result< R > StartsWith(const std::shared_ptr< Bound > &expr, const Literal &lit)
Visit a starts-with bound expression.
Definition expression_visitor.h:163
Base visitor for traversing expression trees.
Definition expression_visitor.h:49
virtual Result< R > And(ParamType left_result, ParamType right_result)=0
Visit an And expression.
virtual Result< R > Predicate(const std::shared_ptr< UnboundPredicate > &pred)=0
Visit an unbound predicate.
virtual Result< R > Not(ParamType child_result)=0
Visit a Not expression.
virtual Result< R > Aggregate(const std::shared_ptr< BoundAggregate > &aggregate)
Visit a bound aggregate.
Definition expression_visitor.h:85
virtual Result< R > Aggregate(const std::shared_ptr< UnboundAggregate > &aggregate)
Visit an unbound aggregate.
Definition expression_visitor.h:93
virtual Result< R > Or(ParamType left_result, ParamType right_result)=0
Visit an Or expression.
virtual Result< R > AlwaysFalse()=0
Visit a False expression (always evaluates to false).
virtual Result< R > Predicate(const std::shared_ptr< BoundPredicate > &pred)=0
Visit a bound predicate.
virtual Result< R > AlwaysTrue()=0
Visit a True expression (always evaluates to true).
Literal is a literal value that is associated with a primitive type.
Definition literal.h:39
Result< R > Visit(const std::shared_ptr< Expression > &expr, V &visitor)
Traverse an expression tree with a visitor.
Definition expression_visitor.h:283