Skip to content

Commit b86dda1

Browse files
committed
feat: scaffolding work for expression
1 parent 55b0436 commit b86dda1

File tree

12 files changed

+1341
-11
lines changed

12 files changed

+1341
-11
lines changed

src/iceberg/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@ set(ICEBERG_SOURCES
2121
arrow_c_data_internal.cc
2222
catalog/in_memory_catalog.cc
2323
expression/expression.cc
24+
expression/expressions.cc
2425
expression/literal.cc
26+
expression/predicate.cc
27+
expression/term.cc
2528
file_reader.cc
2629
file_writer.cc
2730
json_internal.cc

src/iceberg/expression/expressions.cc

Lines changed: 344 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,344 @@
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 "iceberg/expression/expressions.h"
21+
22+
#include "iceberg/exception.h"
23+
#include "iceberg/transform.h"
24+
#include "iceberg/type.h"
25+
26+
namespace iceberg {
27+
28+
// Logical operations
29+
30+
std::shared_ptr<Expression> Expressions::And(std::shared_ptr<Expression> left,
31+
std::shared_ptr<Expression> right) {
32+
if (left->op() == Expression::Operation::kFalse ||
33+
right->op() == Expression::Operation::kFalse) {
34+
return AlwaysFalse();
35+
}
36+
37+
if (left->op() == Expression::Operation::kTrue) {
38+
return right;
39+
}
40+
41+
if (right->op() == Expression::Operation::kTrue) {
42+
return left;
43+
}
44+
45+
return std::make_shared<::iceberg::And>(left, right);
46+
}
47+
48+
std::shared_ptr<Expression> Expressions::Or(std::shared_ptr<Expression> left,
49+
std::shared_ptr<Expression> right) {
50+
if (left->op() == Expression::Operation::kTrue ||
51+
right->op() == Expression::Operation::kTrue) {
52+
return AlwaysTrue();
53+
}
54+
55+
if (left->op() == Expression::Operation::kFalse) {
56+
return right;
57+
}
58+
59+
if (right->op() == Expression::Operation::kFalse) {
60+
return left;
61+
}
62+
63+
return std::make_shared<::iceberg::Or>(left, right);
64+
}
65+
66+
// Transform functions
67+
68+
std::shared_ptr<UnboundTransform> Expressions::Bucket(std::string name,
69+
int32_t num_buckets) {
70+
return std::make_shared<UnboundTransform>(Ref(std::move(name)),
71+
Transform::Bucket(num_buckets));
72+
}
73+
74+
std::shared_ptr<UnboundTransform> Expressions::Year(std::string name) {
75+
return std::make_shared<UnboundTransform>(Ref(std::move(name)), Transform::Year());
76+
}
77+
78+
std::shared_ptr<UnboundTransform> Expressions::Month(std::string name) {
79+
return std::make_shared<UnboundTransform>(Ref(std::move(name)), Transform::Month());
80+
}
81+
82+
std::shared_ptr<UnboundTransform> Expressions::Day(std::string name) {
83+
return std::make_shared<UnboundTransform>(Ref(std::move(name)), Transform::Day());
84+
}
85+
86+
std::shared_ptr<UnboundTransform> Expressions::Hour(std::string name) {
87+
return std::make_shared<UnboundTransform>(Ref(std::move(name)), Transform::Hour());
88+
}
89+
90+
std::shared_ptr<UnboundTransform> Expressions::Truncate(std::string name, int32_t width) {
91+
return std::make_shared<UnboundTransform>(Ref(std::move(name)),
92+
Transform::Truncate(width));
93+
}
94+
95+
std::shared_ptr<UnboundTransform> Expressions::Transform(
96+
std::string name, std::shared_ptr<::iceberg::Transform> transform) {
97+
return std::make_shared<UnboundTransform>(Ref(std::move(name)), std::move(transform));
98+
}
99+
100+
// Template implementations for unary predicates
101+
102+
std::shared_ptr<UnboundPredicate<BoundReference>> Expressions::IsNull(std::string name) {
103+
return IsNull<BoundReference>(Ref(std::move(name)));
104+
}
105+
106+
template <typename B>
107+
std::shared_ptr<UnboundPredicate<B>> Expressions::IsNull(
108+
std::shared_ptr<UnboundTerm<B>> expr) {
109+
return std::make_shared<UnboundPredicate<B>>(Expression::Operation::kIsNull,
110+
std::move(expr));
111+
}
112+
113+
std::shared_ptr<UnboundPredicate<BoundReference>> Expressions::NotNull(std::string name) {
114+
return NotNull<BoundReference>(Ref(std::move(name)));
115+
}
116+
117+
template <typename B>
118+
std::shared_ptr<UnboundPredicate<B>> Expressions::NotNull(
119+
std::shared_ptr<UnboundTerm<B>> expr) {
120+
return std::make_shared<UnboundPredicate<B>>(Expression::Operation::kNotNull,
121+
std::move(expr));
122+
}
123+
124+
std::shared_ptr<UnboundPredicate<BoundReference>> Expressions::IsNaN(std::string name) {
125+
return IsNaN<BoundReference>(Ref(std::move(name)));
126+
}
127+
128+
template <typename B>
129+
std::shared_ptr<UnboundPredicate<B>> Expressions::IsNaN(
130+
std::shared_ptr<UnboundTerm<B>> expr) {
131+
return std::make_shared<UnboundPredicate<B>>(Expression::Operation::kIsNan,
132+
std::move(expr));
133+
}
134+
135+
std::shared_ptr<UnboundPredicate<BoundReference>> Expressions::NotNaN(std::string name) {
136+
return NotNaN<BoundReference>(Ref(std::move(name)));
137+
}
138+
139+
template <typename B>
140+
std::shared_ptr<UnboundPredicate<B>> Expressions::NotNaN(
141+
std::shared_ptr<UnboundTerm<B>> expr) {
142+
return std::make_shared<UnboundPredicate<B>>(Expression::Operation::kNotNan,
143+
std::move(expr));
144+
}
145+
146+
// Template implementations for comparison predicates
147+
148+
std::shared_ptr<UnboundPredicate<BoundReference>> Expressions::LessThan(std::string name,
149+
Literal value) {
150+
return LessThan<BoundReference>(Ref(std::move(name)), std::move(value));
151+
}
152+
153+
template <typename B>
154+
std::shared_ptr<UnboundPredicate<B>> Expressions::LessThan(
155+
std::shared_ptr<UnboundTerm<B>> expr, Literal value) {
156+
return std::make_shared<UnboundPredicate<B>>(Expression::Operation::kLt,
157+
std::move(expr), std::move(value));
158+
}
159+
160+
std::shared_ptr<UnboundPredicate<BoundReference>> Expressions::LessThanOrEqual(
161+
std::string name, Literal value) {
162+
return LessThanOrEqual<BoundReference>(Ref(std::move(name)), std::move(value));
163+
}
164+
165+
template <typename B>
166+
std::shared_ptr<UnboundPredicate<B>> Expressions::LessThanOrEqual(
167+
std::shared_ptr<UnboundTerm<B>> expr, Literal value) {
168+
return std::make_shared<UnboundPredicate<B>>(Expression::Operation::kLtEq,
169+
std::move(expr), std::move(value));
170+
}
171+
172+
std::shared_ptr<UnboundPredicate<BoundReference>> Expressions::GreaterThan(
173+
std::string name, Literal value) {
174+
return GreaterThan<BoundReference>(Ref(std::move(name)), std::move(value));
175+
}
176+
177+
template <typename B>
178+
std::shared_ptr<UnboundPredicate<B>> Expressions::GreaterThan(
179+
std::shared_ptr<UnboundTerm<B>> expr, Literal value) {
180+
return std::make_shared<UnboundPredicate<B>>(Expression::Operation::kGt,
181+
std::move(expr), std::move(value));
182+
}
183+
184+
std::shared_ptr<UnboundPredicate<BoundReference>> Expressions::GreaterThanOrEqual(
185+
std::string name, Literal value) {
186+
return GreaterThanOrEqual<BoundReference>(Ref(std::move(name)), std::move(value));
187+
}
188+
189+
template <typename B>
190+
std::shared_ptr<UnboundPredicate<B>> Expressions::GreaterThanOrEqual(
191+
std::shared_ptr<UnboundTerm<B>> expr, Literal value) {
192+
return std::make_shared<UnboundPredicate<B>>(Expression::Operation::kGtEq,
193+
std::move(expr), std::move(value));
194+
}
195+
196+
std::shared_ptr<UnboundPredicate<BoundReference>> Expressions::Equal(std::string name,
197+
Literal value) {
198+
return Equal<BoundReference>(Ref(std::move(name)), std::move(value));
199+
}
200+
201+
template <typename B>
202+
std::shared_ptr<UnboundPredicate<B>> Expressions::Equal(
203+
std::shared_ptr<UnboundTerm<B>> expr, Literal value) {
204+
return std::make_shared<UnboundPredicate<B>>(Expression::Operation::kEq,
205+
std::move(expr), std::move(value));
206+
}
207+
208+
std::shared_ptr<UnboundPredicate<BoundReference>> Expressions::NotEqual(std::string name,
209+
Literal value) {
210+
return NotEqual<BoundReference>(Ref(std::move(name)), std::move(value));
211+
}
212+
213+
template <typename B>
214+
std::shared_ptr<UnboundPredicate<B>> Expressions::NotEqual(
215+
std::shared_ptr<UnboundTerm<B>> expr, Literal value) {
216+
return std::make_shared<UnboundPredicate<B>>(Expression::Operation::kNotEq,
217+
std::move(expr), std::move(value));
218+
}
219+
220+
// String predicates
221+
222+
std::shared_ptr<UnboundPredicate<BoundReference>> Expressions::StartsWith(
223+
std::string name, std::string value) {
224+
return StartsWith<BoundReference>(Ref(std::move(name)), std::move(value));
225+
}
226+
227+
template <typename B>
228+
std::shared_ptr<UnboundPredicate<B>> Expressions::StartsWith(
229+
std::shared_ptr<UnboundTerm<B>> expr, std::string value) {
230+
return std::make_shared<UnboundPredicate<B>>(Expression::Operation::kStartsWith,
231+
std::move(expr),
232+
Literal::String(std::move(value)));
233+
}
234+
235+
std::shared_ptr<UnboundPredicate<BoundReference>> Expressions::NotStartsWith(
236+
std::string name, std::string value) {
237+
return NotStartsWith<BoundReference>(Ref(std::move(name)), std::move(value));
238+
}
239+
240+
template <typename B>
241+
std::shared_ptr<UnboundPredicate<B>> Expressions::NotStartsWith(
242+
std::shared_ptr<UnboundTerm<B>> expr, std::string value) {
243+
return std::make_shared<UnboundPredicate<B>>(Expression::Operation::kNotStartsWith,
244+
std::move(expr),
245+
Literal::String(std::move(value)));
246+
}
247+
248+
// Template implementations for set predicates
249+
250+
std::shared_ptr<UnboundPredicate<BoundReference>> Expressions::In(
251+
std::string name, std::vector<Literal> values) {
252+
return In<BoundReference>(Ref(std::move(name)), std::move(values));
253+
}
254+
255+
template <typename B>
256+
std::shared_ptr<UnboundPredicate<B>> Expressions::In(std::shared_ptr<UnboundTerm<B>> expr,
257+
std::vector<Literal> values) {
258+
return std::make_shared<UnboundPredicate<B>>(Expression::Operation::kIn,
259+
std::move(expr), std::move(values));
260+
}
261+
262+
std::shared_ptr<UnboundPredicate<BoundReference>> Expressions::In(
263+
std::string name, std::initializer_list<Literal> values) {
264+
return In<BoundReference>(Ref(std::move(name)), std::vector<Literal>(values));
265+
}
266+
267+
template <typename B>
268+
std::shared_ptr<UnboundPredicate<B>> Expressions::In(
269+
std::shared_ptr<UnboundTerm<B>> expr, std::initializer_list<Literal> values) {
270+
return In<B>(std::move(expr), std::vector<Literal>(values));
271+
}
272+
273+
std::shared_ptr<UnboundPredicate<BoundReference>> Expressions::NotIn(
274+
std::string name, std::vector<Literal> values) {
275+
return NotIn<BoundReference>(Ref(std::move(name)), std::move(values));
276+
}
277+
278+
template <typename B>
279+
std::shared_ptr<UnboundPredicate<B>> Expressions::NotIn(
280+
std::shared_ptr<UnboundTerm<B>> expr, std::vector<Literal> values) {
281+
return std::make_shared<UnboundPredicate<B>>(Expression::Operation::kNotIn,
282+
std::move(expr), std::move(values));
283+
}
284+
285+
std::shared_ptr<UnboundPredicate<BoundReference>> Expressions::NotIn(
286+
std::string name, std::initializer_list<Literal> values) {
287+
return NotIn<BoundReference>(Ref(std::move(name)), std::vector<Literal>(values));
288+
}
289+
290+
template <typename B>
291+
std::shared_ptr<UnboundPredicate<B>> Expressions::NotIn(
292+
std::shared_ptr<UnboundTerm<B>> expr, std::initializer_list<Literal> values) {
293+
return NotIn<B>(expr, std::vector<Literal>(values));
294+
}
295+
296+
// Template implementations for generic predicate factory
297+
298+
std::shared_ptr<UnboundPredicate<BoundReference>> Expressions::Predicate(
299+
Expression::Operation op, std::string name, Literal value) {
300+
return std::make_shared<UnboundPredicate<BoundReference>>(op, Ref(std::move(name)),
301+
std::move(value));
302+
}
303+
304+
std::shared_ptr<UnboundPredicate<BoundReference>> Expressions::Predicate(
305+
Expression::Operation op, std::string name, std::vector<Literal> values) {
306+
return std::make_shared<UnboundPredicate<BoundReference>>(op, Ref(std::move(name)),
307+
std::move(values));
308+
}
309+
310+
std::shared_ptr<UnboundPredicate<BoundReference>> Expressions::Predicate(
311+
Expression::Operation op, std::string name) {
312+
return std::make_shared<UnboundPredicate<BoundReference>>(op, Ref(std::move(name)));
313+
}
314+
315+
template <typename B>
316+
std::shared_ptr<UnboundPredicate<B>> Expressions::Predicate(
317+
Expression::Operation op, std::shared_ptr<UnboundTerm<B>> expr,
318+
std::vector<Literal> values) {
319+
return std::make_shared<UnboundPredicate<B>>(op, std::move(expr), std::move(values));
320+
}
321+
322+
template <typename B>
323+
std::shared_ptr<UnboundPredicate<B>> Expressions::Predicate(
324+
Expression::Operation op, std::shared_ptr<UnboundTerm<B>> expr) {
325+
return std::make_shared<UnboundPredicate<B>>(op, std::move(expr));
326+
}
327+
328+
// Constants
329+
330+
std::shared_ptr<True> Expressions::AlwaysTrue() { return True::Instance(); }
331+
332+
std::shared_ptr<False> Expressions::AlwaysFalse() { return False::Instance(); }
333+
334+
// Utilities
335+
336+
std::shared_ptr<NamedReference> Expressions::Ref(std::string name) {
337+
return std::make_shared<NamedReference>(std::move(name));
338+
}
339+
340+
Literal Expressions::Lit(Literal::Value value, std::shared_ptr<PrimitiveType> type) {
341+
throw IcebergError("Literal creation is not implemented");
342+
}
343+
344+
} // namespace iceberg

0 commit comments

Comments
 (0)