iceberg-cpp
Loading...
Searching...
No Matches
expression.h
Go to the documentation of this file.
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20#pragma once
21
24
25#include <memory>
26#include <string>
27
28#include "iceberg/iceberg_export.h"
29#include "iceberg/result.h"
30#include "iceberg/type_fwd.h"
32#include "iceberg/util/macros.h"
33
34namespace iceberg {
35
37class ICEBERG_EXPORT Expression : public util::Formattable {
38 public:
40 enum class Operation {
41 kTrue,
42 kFalse,
43 kIsNull,
44 kNotNull,
45 kIsNan,
46 kNotNan,
47 kLt,
48 kLtEq,
49 kGt,
50 kGtEq,
51 kEq,
52 kNotEq,
53 kIn,
54 kNotIn,
55 kNot,
56 kAnd,
57 kOr,
58 kStartsWith,
59 kNotStartsWith,
60 kCount,
61 kCountNull,
62 kCountStar,
63 kMax,
64 kMin
65 };
66
67 virtual ~Expression() = default;
68
70 virtual Operation op() const = 0;
71
73 virtual Result<std::shared_ptr<Expression>> Negate() const {
74 return NotSupported("Expression cannot be negated");
75 }
76
80 virtual bool Equals(const Expression& other) const {
81 // only bound predicates can be equivalent
82 return false;
83 }
84
85 std::string ToString() const override { return "Expression"; }
86
87 virtual bool is_unbound_predicate() const { return false; }
88 virtual bool is_bound_predicate() const { return false; }
89 virtual bool is_unbound_aggregate() const { return false; }
90 virtual bool is_bound_aggregate() const { return false; }
91};
92
96class ICEBERG_EXPORT True : public Expression {
97 public:
99 static const std::shared_ptr<True>& Instance();
100
101 Operation op() const override { return Operation::kTrue; }
102
103 std::string ToString() const override { return "true"; }
104
105 Result<std::shared_ptr<Expression>> Negate() const override;
106
107 bool Equals(const Expression& other) const override {
108 return other.op() == Operation::kTrue;
109 }
110
111 private:
112 constexpr True() = default;
113};
114
116class ICEBERG_EXPORT False : public Expression {
117 public:
119 static const std::shared_ptr<False>& Instance();
120
121 Operation op() const override { return Operation::kFalse; }
122
123 std::string ToString() const override { return "false"; }
124
125 Result<std::shared_ptr<Expression>> Negate() const override;
126
127 bool Equals(const Expression& other) const override {
128 return other.op() == Operation::kFalse;
129 }
130
131 private:
132 constexpr False() = default;
133};
134
139class ICEBERG_EXPORT And : public Expression {
140 public:
145 static Result<std::unique_ptr<And>> Make(std::shared_ptr<Expression> left,
146 std::shared_ptr<Expression> right);
147
157 template <typename... Args>
158 static Result<std::shared_ptr<Expression>> MakeFolded(std::shared_ptr<Expression> left,
159 std::shared_ptr<Expression> right,
160 Args&&... args)
161 requires std::conjunction_v<std::is_same<Args, std::shared_ptr<Expression>>...>
162 {
163 if constexpr (sizeof...(args) == 0) {
164 if (left->op() == Expression::Operation::kFalse ||
165 right->op() == Expression::Operation::kFalse) {
166 return False::Instance();
167 }
168
169 if (left->op() == Expression::Operation::kTrue) {
170 return right;
171 }
172
173 if (right->op() == Expression::Operation::kTrue) {
174 return left;
175 }
176
177 return And::Make(std::move(left), std::move(right));
178 } else {
179 ICEBERG_ASSIGN_OR_THROW(auto and_expr,
180 And::Make(std::move(left), std::move(right)));
181
182 return And::MakeFolded(std::move(and_expr), std::forward<Args>(args)...);
183 }
184 }
185
189 const std::shared_ptr<Expression>& left() const { return left_; }
190
194 const std::shared_ptr<Expression>& right() const { return right_; }
195
196 Operation op() const override { return Operation::kAnd; }
197
198 std::string ToString() const override;
199
200 Result<std::shared_ptr<Expression>> Negate() const override;
201
202 bool Equals(const Expression& other) const override;
203
204 private:
205 And(std::shared_ptr<Expression> left, std::shared_ptr<Expression> right);
206
207 std::shared_ptr<Expression> left_;
208 std::shared_ptr<Expression> right_;
209};
210
215class ICEBERG_EXPORT Or : public Expression {
216 public:
221 static Result<std::unique_ptr<Or>> Make(std::shared_ptr<Expression> left,
222 std::shared_ptr<Expression> right);
223
233 template <typename... Args>
234 static Result<std::shared_ptr<Expression>> MakeFolded(std::shared_ptr<Expression> left,
235 std::shared_ptr<Expression> right,
236 Args&&... args)
237 requires std::conjunction_v<std::is_same<Args, std::shared_ptr<Expression>>...>
238 {
239 if constexpr (sizeof...(args) == 0) {
240 if (left->op() == Expression::Operation::kTrue ||
241 right->op() == Expression::Operation::kTrue) {
242 return True::Instance();
243 }
244
245 if (left->op() == Expression::Operation::kFalse) {
246 return right;
247 }
248
249 if (right->op() == Expression::Operation::kFalse) {
250 return left;
251 }
252
253 return Or::Make(std::move(left), std::move(right));
254 } else {
255 ICEBERG_ASSIGN_OR_THROW(auto or_expr, Or::Make(std::move(left), std::move(right)));
256
257 return Or::MakeFolded(std::move(or_expr), std::forward<Args>(args)...);
258 }
259 }
260
264 const std::shared_ptr<Expression>& left() const { return left_; }
265
269 const std::shared_ptr<Expression>& right() const { return right_; }
270
271 Operation op() const override { return Operation::kOr; }
272
273 std::string ToString() const override;
274
275 Result<std::shared_ptr<Expression>> Negate() const override;
276
277 bool Equals(const Expression& other) const override;
278
279 private:
280 Or(std::shared_ptr<Expression> left, std::shared_ptr<Expression> right);
281
282 std::shared_ptr<Expression> left_;
283 std::shared_ptr<Expression> right_;
284};
285
289class ICEBERG_EXPORT Not : public Expression {
290 public:
295 static Result<std::unique_ptr<Not>> Make(std::shared_ptr<Expression> child);
296
304 static Result<std::shared_ptr<Expression>> MakeFolded(
305 std::shared_ptr<Expression> child);
306
310 const std::shared_ptr<Expression>& child() const { return child_; }
311
312 Operation op() const override { return Operation::kNot; }
313
314 std::string ToString() const override;
315
316 Result<std::shared_ptr<Expression>> Negate() const override;
317
318 bool Equals(const Expression& other) const override;
319
320 private:
321 explicit Not(std::shared_ptr<Expression> child);
322
323 std::shared_ptr<Expression> child_;
324};
325
327ICEBERG_EXPORT std::string_view ToString(Expression::Operation op);
328
330ICEBERG_EXPORT Result<Expression::Operation> Negate(Expression::Operation op);
331
338template <typename B>
339class ICEBERG_EXPORT Unbound {
340 public:
346 virtual Result<std::shared_ptr<B>> Bind(const Schema& schema,
347 bool case_sensitive) const = 0;
348
350 Result<std::shared_ptr<B>> Bind(const Schema& schema) const;
351
353 virtual std::shared_ptr<class NamedReference> reference() = 0;
354};
355
360class ICEBERG_EXPORT Bound {
361 public:
362 virtual ~Bound();
363
365 virtual Result<Literal> Evaluate(const StructLike& data) const = 0;
366
368 virtual std::shared_ptr<class BoundReference> reference() = 0;
369};
370
371} // namespace iceberg
An Expression that represents a logical AND operation between two expressions.
Definition expression.h:139
static Result< std::shared_ptr< Expression > > MakeFolded(std::shared_ptr< Expression > left, std::shared_ptr< Expression > right, Args &&... args)
Creates a folded And expression from two sub-expressions.
Definition expression.h:158
Operation op() const override
Returns the operation for an expression node.
Definition expression.h:196
const std::shared_ptr< Expression > & left() const
Returns the left operand of the AND expression.
Definition expression.h:189
const std::shared_ptr< Expression > & right() const
Returns the right operand of the AND expression.
Definition expression.h:194
Interface for bound expressions that can be evaluated.
Definition expression.h:360
virtual std::shared_ptr< class BoundReference > reference()=0
Returns the underlying bound reference for this term.
virtual Result< Literal > Evaluate(const StructLike &data) const =0
Evaluate this expression against a row-based data.
Represents a boolean expression tree.
Definition expression.h:37
std::string ToString() const override
Get a user-readable string representation.
Definition expression.h:85
Operation
Operation types for expressions.
Definition expression.h:40
virtual Operation op() const =0
Returns the operation for an expression node.
virtual bool Equals(const Expression &other) const
Returns whether this expression will accept the same values as another.
Definition expression.h:80
virtual Result< std::shared_ptr< Expression > > Negate() const
Returns the negation of this expression, equivalent to not(this).
Definition expression.h:73
An expression that is always false.
Definition expression.h:116
std::string ToString() const override
Get a user-readable string representation.
Definition expression.h:123
bool Equals(const Expression &other) const override
Returns whether this expression will accept the same values as another.
Definition expression.h:127
Operation op() const override
Returns the operation for an expression node.
Definition expression.h:121
An Expression that represents logical NOT operation.
Definition expression.h:289
const std::shared_ptr< Expression > & child() const
Returns the child expression.
Definition expression.h:310
Operation op() const override
Returns the operation for an expression node.
Definition expression.h:312
An Expression that represents a logical OR operation between two expressions.
Definition expression.h:215
static Result< std::shared_ptr< Expression > > MakeFolded(std::shared_ptr< Expression > left, std::shared_ptr< Expression > right, Args &&... args)
Creates a folded Or expression from two sub-expressions.
Definition expression.h:234
const std::shared_ptr< Expression > & left() const
Returns the left operand of the OR expression.
Definition expression.h:264
const std::shared_ptr< Expression > & right() const
Returns the right operand of the OR expression.
Definition expression.h:269
Operation op() const override
Returns the operation for an expression node.
Definition expression.h:271
A schema for a Table.
Definition schema.h:49
An immutable struct-like wrapper.
Definition struct_like.h:62
An Expression that is always true.
Definition expression.h:96
bool Equals(const Expression &other) const override
Returns whether this expression will accept the same values as another.
Definition expression.h:107
Operation op() const override
Returns the operation for an expression node.
Definition expression.h:101
std::string ToString() const override
Get a user-readable string representation.
Definition expression.h:103
Interface for unbound expressions that need schema binding.
Definition expression.h:339
virtual Result< std::shared_ptr< B > > Bind(const Schema &schema, bool case_sensitive) const =0
Bind this expression to a concrete schema.
virtual std::shared_ptr< class NamedReference > reference()=0
Returns the underlying named reference for this unbound term.
Interface for objects that can be formatted via std::format.
Definition formattable.h:36