Skip to content

Commit b33d86c

Browse files
committed
Part of expr works (unbound)
1 parent c00ee8f commit b33d86c

File tree

8 files changed

+204
-84
lines changed

8 files changed

+204
-84
lines changed

src/iceberg/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ set(ICEBERG_SOURCES
2323
demo.cc
2424
expression/expression.cc
2525
expression/literal.cc
26+
expression/term.cc
2627
file_reader.cc
2728
json_internal.cc
2829
manifest_entry.cc

src/iceberg/expression/common.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
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+
22+
namespace iceberg {
23+
24+
template <typename T>
25+
concept Bindable = requires(T expr) {
26+
{ expr.Bind() };
27+
};
28+
29+
} // namespace iceberg

src/iceberg/expression/expression.cc

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121

2222
#include <format>
2323

24+
#include "iceberg/util/checked_cast.h"
25+
2426
namespace iceberg {
2527

2628
// True implementation
@@ -29,25 +31,25 @@ const std::shared_ptr<True>& True::Instance() {
2931
return instance;
3032
}
3133

32-
std::shared_ptr<Expression> True::Negate() const { return False::Instance(); }
34+
std::shared_ptr<Predicate> True::Negate() const { return False::Instance(); }
3335

3436
// False implementation
3537
const std::shared_ptr<False>& False::Instance() {
3638
static const std::shared_ptr<False> instance = std::shared_ptr<False>(new False());
3739
return instance;
3840
}
3941

40-
std::shared_ptr<Expression> False::Negate() const { return True::Instance(); }
42+
std::shared_ptr<Predicate> False::Negate() const { return True::Instance(); }
4143

4244
// And implementation
43-
And::And(std::shared_ptr<Expression> left, std::shared_ptr<Expression> right)
45+
And::And(std::shared_ptr<Predicate> left, std::shared_ptr<Predicate> right)
4446
: left_(std::move(left)), right_(std::move(right)) {}
4547

4648
std::string And::ToString() const {
4749
return std::format("({} and {})", left_->ToString(), right_->ToString());
4850
}
4951

50-
std::shared_ptr<Expression> And::Negate() const {
52+
std::shared_ptr<Predicate> And::Negate() const {
5153
// De Morgan's law: not(A and B) = (not A) or (not B)
5254
auto left_negated = left_->Negate();
5355
auto right_negated = right_->Negate();
@@ -56,22 +58,22 @@ std::shared_ptr<Expression> And::Negate() const {
5658

5759
bool And::Equals(const Expression& expr) const {
5860
if (expr.op() == Operation::kAnd) {
59-
const auto& other = static_cast<const And&>(expr);
61+
const auto& other = iceberg::internal::checked_cast<const And&>(expr);
6062
return (left_->Equals(*other.left()) && right_->Equals(*other.right())) ||
6163
(left_->Equals(*other.right()) && right_->Equals(*other.left()));
6264
}
6365
return false;
6466
}
6567

6668
// Or implementation
67-
Or::Or(std::shared_ptr<Expression> left, std::shared_ptr<Expression> right)
69+
Or::Or(std::shared_ptr<Predicate> left, std::shared_ptr<Predicate> right)
6870
: left_(std::move(left)), right_(std::move(right)) {}
6971

7072
std::string Or::ToString() const {
7173
return std::format("({} or {})", left_->ToString(), right_->ToString());
7274
}
7375

74-
std::shared_ptr<Expression> Or::Negate() const {
76+
std::shared_ptr<Predicate> Or::Negate() const {
7577
// De Morgan's law: not(A or B) = (not A) and (not B)
7678
auto left_negated = left_->Negate();
7779
auto right_negated = right_->Negate();
@@ -80,7 +82,7 @@ std::shared_ptr<Expression> Or::Negate() const {
8082

8183
bool Or::Equals(const Expression& expr) const {
8284
if (expr.op() == Operation::kOr) {
83-
const auto& other = static_cast<const Or&>(expr);
85+
const auto& other = iceberg::internal::checked_cast<const Or&>(expr);
8486
return (left_->Equals(*other.left()) && right_->Equals(*other.right())) ||
8587
(left_->Equals(*other.right()) && right_->Equals(*other.left()));
8688
}

src/iceberg/expression/expression.h

Lines changed: 84 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -30,46 +30,73 @@
3030

3131
namespace iceberg {
3232

33+
/// Operation types for expressions
34+
enum class Operation {
35+
kTrue,
36+
kFalse,
37+
kIsNull,
38+
kNotNull,
39+
kIsNan,
40+
kNotNan,
41+
kLt,
42+
kLtEq,
43+
kGt,
44+
kGtEq,
45+
kEq,
46+
kNotEq,
47+
kIn,
48+
kNotIn,
49+
kNot,
50+
kAnd,
51+
kOr,
52+
kStartsWith,
53+
kNotStartsWith,
54+
kCount,
55+
kCountStar,
56+
kMax,
57+
kMin
58+
};
59+
60+
/// \brief Returns whether the operation is a predicate operation.
61+
constexpr bool IsPredicate(Operation op) {
62+
switch (op) {
63+
case Operation::kTrue:
64+
case Operation::kFalse:
65+
case Operation::kIsNull:
66+
case Operation::kNotNull:
67+
case Operation::kIsNan:
68+
case Operation::kNotNan:
69+
case Operation::kLt:
70+
case Operation::kLtEq:
71+
case Operation::kGt:
72+
case Operation::kGtEq:
73+
case Operation::kEq:
74+
case Operation::kNotEq:
75+
case Operation::kIn:
76+
case Operation::kNotIn:
77+
case Operation::kNot:
78+
case Operation::kAnd:
79+
case Operation::kOr:
80+
case Operation::kStartsWith:
81+
case Operation::kNotStartsWith:
82+
return true;
83+
case Operation::kCount:
84+
case Operation::kCountStar:
85+
case Operation::kMax:
86+
case Operation::kMin:
87+
return false;
88+
}
89+
return false;
90+
}
91+
3392
/// \brief Represents a boolean expression tree.
3493
class ICEBERG_EXPORT Expression {
3594
public:
36-
/// Operation types for expressions
37-
enum class Operation {
38-
kTrue,
39-
kFalse,
40-
kIsNull,
41-
kNotNull,
42-
kIsNan,
43-
kNotNan,
44-
kLt,
45-
kLtEq,
46-
kGt,
47-
kGtEq,
48-
kEq,
49-
kNotEq,
50-
kIn,
51-
kNotIn,
52-
kNot,
53-
kAnd,
54-
kOr,
55-
kStartsWith,
56-
kNotStartsWith,
57-
kCount,
58-
kCountStar,
59-
kMax,
60-
kMin
61-
};
62-
6395
virtual ~Expression() = default;
6496

6597
/// \brief Returns the operation for an expression node.
6698
virtual Operation op() const = 0;
6799

68-
/// \brief Returns the negation of this expression, equivalent to not(this).
69-
virtual std::shared_ptr<Expression> Negate() const {
70-
throw IcebergError("Expression cannot be negated");
71-
}
72-
73100
/// \brief Returns whether this expression will accept the same values as another.
74101
/// \param other another expression
75102
/// \return true if the expressions are equivalent
@@ -78,13 +105,19 @@ class ICEBERG_EXPORT Expression {
78105
return false;
79106
}
80107

81-
virtual std::string ToString() const { return "Expression"; }
108+
virtual std::string ToString() const = 0;
109+
};
110+
111+
class ICEBERG_EXPORT Predicate : public Expression {
112+
public:
113+
/// \brief Returns a negated version of this predicate.
114+
virtual std::shared_ptr<Predicate> Negate() const = 0;
82115
};
83116

84117
/// \brief An Expression that is always true.
85118
///
86119
/// Represents a boolean predicate that always evaluates to true.
87-
class ICEBERG_EXPORT True : public Expression {
120+
class ICEBERG_EXPORT True : public Predicate {
88121
public:
89122
/// \brief Returns the singleton instance
90123
static const std::shared_ptr<True>& Instance();
@@ -93,7 +126,7 @@ class ICEBERG_EXPORT True : public Expression {
93126

94127
std::string ToString() const override { return "true"; }
95128

96-
std::shared_ptr<Expression> Negate() const override;
129+
std::shared_ptr<Predicate> Negate() const override;
97130

98131
bool Equals(const Expression& other) const override {
99132
return other.op() == Operation::kTrue;
@@ -104,7 +137,7 @@ class ICEBERG_EXPORT True : public Expression {
104137
};
105138

106139
/// \brief An expression that is always false.
107-
class ICEBERG_EXPORT False : public Expression {
140+
class ICEBERG_EXPORT False : public Predicate {
108141
public:
109142
/// \brief Returns the singleton instance
110143
static const std::shared_ptr<False>& Instance();
@@ -113,7 +146,7 @@ class ICEBERG_EXPORT False : public Expression {
113146

114147
std::string ToString() const override { return "false"; }
115148

116-
std::shared_ptr<Expression> Negate() const override;
149+
std::shared_ptr<Predicate> Negate() const override;
117150

118151
bool Equals(const Expression& other) const override {
119152
return other.op() == Operation::kFalse;
@@ -127,70 +160,70 @@ class ICEBERG_EXPORT False : public Expression {
127160
///
128161
/// This expression evaluates to true if and only if both of its child expressions
129162
/// evaluate to true.
130-
class ICEBERG_EXPORT And : public Expression {
163+
class ICEBERG_EXPORT And : public Predicate {
131164
public:
132165
/// \brief Constructs an And expression from two sub-expressions.
133166
///
134167
/// \param left The left operand of the AND expression
135168
/// \param right The right operand of the AND expression
136-
And(std::shared_ptr<Expression> left, std::shared_ptr<Expression> right);
169+
And(std::shared_ptr<Predicate> left, std::shared_ptr<Predicate> right);
137170

138171
/// \brief Returns the left operand of the AND expression.
139172
///
140173
/// \return The left operand of the AND expression
141-
const std::shared_ptr<Expression>& left() const { return left_; }
174+
const std::shared_ptr<Predicate>& left() const { return left_; }
142175

143176
/// \brief Returns the right operand of the AND expression.
144177
///
145178
/// \return The right operand of the AND expression
146-
const std::shared_ptr<Expression>& right() const { return right_; }
179+
const std::shared_ptr<Predicate>& right() const { return right_; }
147180

148181
Operation op() const override { return Operation::kAnd; }
149182

150183
std::string ToString() const override;
151184

152-
std::shared_ptr<Expression> Negate() const override;
185+
std::shared_ptr<Predicate> Negate() const override;
153186

154187
bool Equals(const Expression& other) const override;
155188

156189
private:
157-
std::shared_ptr<Expression> left_;
158-
std::shared_ptr<Expression> right_;
190+
std::shared_ptr<Predicate> left_;
191+
std::shared_ptr<Predicate> right_;
159192
};
160193

161194
/// \brief An Expression that represents a logical OR operation between two expressions.
162195
///
163196
/// This expression evaluates to true if at least one of its child expressions
164197
/// evaluates to true.
165-
class ICEBERG_EXPORT Or : public Expression {
198+
class ICEBERG_EXPORT Or : public Predicate {
166199
public:
167200
/// \brief Constructs an Or expression from two sub-expressions.
168201
///
169202
/// \param left The left operand of the OR expression
170203
/// \param right The right operand of the OR expression
171-
Or(std::shared_ptr<Expression> left, std::shared_ptr<Expression> right);
204+
Or(std::shared_ptr<Predicate> left, std::shared_ptr<Predicate> right);
172205

173206
/// \brief Returns the left operand of the OR expression.
174207
///
175208
/// \return The left operand of the OR expression
176-
const std::shared_ptr<Expression>& left() const { return left_; }
209+
const std::shared_ptr<Predicate>& left() const { return left_; }
177210

178211
/// \brief Returns the right operand of the OR expression.
179212
///
180213
/// \return The right operand of the OR expression
181-
const std::shared_ptr<Expression>& right() const { return right_; }
214+
const std::shared_ptr<Predicate>& right() const { return right_; }
182215

183216
Operation op() const override { return Operation::kOr; }
184217

185218
std::string ToString() const override;
186219

187-
std::shared_ptr<Expression> Negate() const override;
220+
std::shared_ptr<Predicate> Negate() const override;
188221

189222
bool Equals(const Expression& other) const override;
190223

191224
private:
192-
std::shared_ptr<Expression> left_;
193-
std::shared_ptr<Expression> right_;
225+
std::shared_ptr<Predicate> left_;
226+
std::shared_ptr<Predicate> right_;
194227
};
195228

196229
} // namespace iceberg

src/iceberg/expression/literal.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919

2020
#pragma once
2121

22+
/// \file iceberg/expression/literal.h
23+
/// Literal class for Iceberg table operations.
24+
2225
#include <compare>
2326
#include <memory>
2427
#include <string>

src/iceberg/expression/term.cc

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
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+
#include "term.h"

0 commit comments

Comments
 (0)