Skip to content

Commit 4fbff65

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

File tree

7 files changed

+1305
-0
lines changed

7 files changed

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

0 commit comments

Comments
 (0)