| /* | |
| * Licensed to the Apache Software Foundation (ASF) under one | |
| * or more contributor license agreements. See the NOTICE file | |
| * distributed with this work for additional information | |
| * regarding copyright ownership. The ASF licenses this file | |
| * to you under the Apache License, Version 2.0 (the | |
| * "License"); you may not use this file except in compliance | |
| * with the License. You may obtain a copy of the License at | |
| * | |
| * http://www.apache.org/licenses/LICENSE-2.0 | |
| * | |
| * Unless required by applicable law or agreed to in writing, | |
| * software distributed under the License is distributed on an | |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
| * KIND, either express or implied. See the License for the | |
| * specific language governing permissions and limitations | |
| * under the License. | |
| */ | |
| #include "iceberg/expression/expressions.h" | |
| #include "iceberg/exception.h" | |
| #include "iceberg/expression/aggregate.h" | |
| #include "iceberg/transform.h" | |
| #include "iceberg/type.h" | |
| #include "iceberg/util/macros.h" | |
| namespace iceberg { | |
| // Logical NOT operation | |
| std::shared_ptr<Expression> Expressions::Not(std::shared_ptr<Expression> child) { | |
| ICEBERG_ASSIGN_OR_THROW(auto not_expr, ::iceberg::Not::MakeFolded(std::move(child))); | |
| return not_expr; | |
| } | |
| // Transform functions | |
| std::shared_ptr<UnboundTransform> Expressions::Bucket(std::string name, | |
| int32_t num_buckets) { | |
| ICEBERG_ASSIGN_OR_THROW( | |
| auto transform, | |
| UnboundTransform::Make(Ref(std::move(name)), Transform::Bucket(num_buckets))); | |
| return transform; | |
| } | |
| std::shared_ptr<UnboundTransform> Expressions::Year(std::string name) { | |
| ICEBERG_ASSIGN_OR_THROW( | |
| auto transform, UnboundTransform::Make(Ref(std::move(name)), Transform::Year())); | |
| return transform; | |
| } | |
| std::shared_ptr<UnboundTransform> Expressions::Month(std::string name) { | |
| ICEBERG_ASSIGN_OR_THROW( | |
| auto transform, UnboundTransform::Make(Ref(std::move(name)), Transform::Month())); | |
| return transform; | |
| } | |
| std::shared_ptr<UnboundTransform> Expressions::Day(std::string name) { | |
| ICEBERG_ASSIGN_OR_THROW(auto transform, | |
| UnboundTransform::Make(Ref(std::move(name)), Transform::Day())); | |
| return transform; | |
| } | |
| std::shared_ptr<UnboundTransform> Expressions::Hour(std::string name) { | |
| ICEBERG_ASSIGN_OR_THROW( | |
| auto transform, UnboundTransform::Make(Ref(std::move(name)), Transform::Hour())); | |
| return transform; | |
| } | |
| std::shared_ptr<UnboundTransform> Expressions::Truncate(std::string name, int32_t width) { | |
| ICEBERG_ASSIGN_OR_THROW( | |
| auto transform, | |
| UnboundTransform::Make(Ref(std::move(name)), Transform::Truncate(width))); | |
| return transform; | |
| } | |
| std::shared_ptr<UnboundTransform> Expressions::Transform( | |
| std::string name, std::shared_ptr<::iceberg::Transform> transform) { | |
| ICEBERG_ASSIGN_OR_THROW( | |
| auto unbound_transform, | |
| UnboundTransform::Make(Ref(std::move(name)), std::move(transform))); | |
| return unbound_transform; | |
| } | |
| // Aggregates | |
| std::shared_ptr<UnboundAggregateImpl<BoundReference>> Expressions::Count( | |
| std::string name) { | |
| return Count(Ref(std::move(name))); | |
| } | |
| std::shared_ptr<UnboundAggregateImpl<BoundReference>> Expressions::Count( | |
| std::shared_ptr<UnboundTerm<BoundReference>> expr) { | |
| ICEBERG_ASSIGN_OR_THROW(auto agg, UnboundAggregateImpl<BoundReference>::Make( | |
| Expression::Operation::kCount, std::move(expr))); | |
| return agg; | |
| } | |
| std::shared_ptr<UnboundAggregateImpl<BoundReference>> Expressions::CountNull( | |
| std::string name) { | |
| return CountNull(Ref(std::move(name))); | |
| } | |
| std::shared_ptr<UnboundAggregateImpl<BoundReference>> Expressions::CountNull( | |
| std::shared_ptr<UnboundTerm<BoundReference>> expr) { | |
| ICEBERG_ASSIGN_OR_THROW(auto agg, | |
| UnboundAggregateImpl<BoundReference>::Make( | |
| Expression::Operation::kCountNull, std::move(expr))); | |
| return agg; | |
| } | |
| std::shared_ptr<UnboundAggregateImpl<BoundReference>> Expressions::CountNotNull( | |
| std::string name) { | |
| return CountNotNull(Ref(std::move(name))); | |
| } | |
| std::shared_ptr<UnboundAggregateImpl<BoundReference>> Expressions::CountNotNull( | |
| std::shared_ptr<UnboundTerm<BoundReference>> expr) { | |
| ICEBERG_ASSIGN_OR_THROW(auto agg, UnboundAggregateImpl<BoundReference>::Make( | |
| Expression::Operation::kCount, std::move(expr))); | |
| return agg; | |
| } | |
| std::shared_ptr<UnboundAggregateImpl<BoundReference>> Expressions::CountStar() { | |
| ICEBERG_ASSIGN_OR_THROW(auto agg, UnboundAggregateImpl<BoundReference>::Make( | |
| Expression::Operation::kCountStar, nullptr)); | |
| return agg; | |
| } | |
| std::shared_ptr<UnboundAggregateImpl<BoundReference>> Expressions::Max(std::string name) { | |
| return Max(Ref(std::move(name))); | |
| } | |
| std::shared_ptr<UnboundAggregateImpl<BoundReference>> Expressions::Max( | |
| std::shared_ptr<UnboundTerm<BoundReference>> expr) { | |
| ICEBERG_ASSIGN_OR_THROW(auto agg, UnboundAggregateImpl<BoundReference>::Make( | |
| Expression::Operation::kMax, std::move(expr))); | |
| return agg; | |
| } | |
| std::shared_ptr<UnboundAggregateImpl<BoundTransform>> Expressions::Max( | |
| std::shared_ptr<UnboundTerm<BoundTransform>> expr) { | |
| ICEBERG_ASSIGN_OR_THROW(auto agg, UnboundAggregateImpl<BoundTransform>::Make( | |
| Expression::Operation::kMax, std::move(expr))); | |
| return agg; | |
| } | |
| std::shared_ptr<UnboundAggregateImpl<BoundReference>> Expressions::Min(std::string name) { | |
| return Min(Ref(std::move(name))); | |
| } | |
| std::shared_ptr<UnboundAggregateImpl<BoundReference>> Expressions::Min( | |
| std::shared_ptr<UnboundTerm<BoundReference>> expr) { | |
| ICEBERG_ASSIGN_OR_THROW(auto agg, UnboundAggregateImpl<BoundReference>::Make( | |
| Expression::Operation::kMin, std::move(expr))); | |
| return agg; | |
| } | |
| std::shared_ptr<UnboundAggregateImpl<BoundTransform>> Expressions::Min( | |
| std::shared_ptr<UnboundTerm<BoundTransform>> expr) { | |
| ICEBERG_ASSIGN_OR_THROW(auto agg, UnboundAggregateImpl<BoundTransform>::Make( | |
| Expression::Operation::kMin, std::move(expr))); | |
| return agg; | |
| } | |
| // Template implementations for unary predicates | |
| std::shared_ptr<UnboundPredicateImpl<BoundReference>> Expressions::IsNull( | |
| std::string name) { | |
| return IsNull<BoundReference>(Ref(std::move(name))); | |
| } | |
| std::shared_ptr<UnboundPredicateImpl<BoundReference>> Expressions::NotNull( | |
| std::string name) { | |
| return NotNull<BoundReference>(Ref(std::move(name))); | |
| } | |
| std::shared_ptr<UnboundPredicateImpl<BoundReference>> Expressions::IsNaN( | |
| std::string name) { | |
| return IsNaN<BoundReference>(Ref(std::move(name))); | |
| } | |
| std::shared_ptr<UnboundPredicateImpl<BoundReference>> Expressions::NotNaN( | |
| std::string name) { | |
| return NotNaN<BoundReference>(Ref(std::move(name))); | |
| } | |
| // Template implementations for comparison predicates | |
| std::shared_ptr<UnboundPredicateImpl<BoundReference>> Expressions::LessThan( | |
| std::string name, Literal value) { | |
| return LessThan<BoundReference>(Ref(std::move(name)), std::move(value)); | |
| } | |
| std::shared_ptr<UnboundPredicateImpl<BoundReference>> Expressions::LessThanOrEqual( | |
| std::string name, Literal value) { | |
| return LessThanOrEqual<BoundReference>(Ref(std::move(name)), std::move(value)); | |
| } | |
| std::shared_ptr<UnboundPredicateImpl<BoundReference>> Expressions::GreaterThan( | |
| std::string name, Literal value) { | |
| return GreaterThan<BoundReference>(Ref(std::move(name)), std::move(value)); | |
| } | |
| std::shared_ptr<UnboundPredicateImpl<BoundReference>> Expressions::GreaterThanOrEqual( | |
| std::string name, Literal value) { | |
| return GreaterThanOrEqual<BoundReference>(Ref(std::move(name)), std::move(value)); | |
| } | |
| std::shared_ptr<UnboundPredicateImpl<BoundReference>> Expressions::Equal(std::string name, | |
| Literal value) { | |
| return Equal<BoundReference>(Ref(std::move(name)), std::move(value)); | |
| } | |
| std::shared_ptr<UnboundPredicateImpl<BoundReference>> Expressions::NotEqual( | |
| std::string name, Literal value) { | |
| return NotEqual<BoundReference>(Ref(std::move(name)), std::move(value)); | |
| } | |
| // String predicates | |
| std::shared_ptr<UnboundPredicateImpl<BoundReference>> Expressions::StartsWith( | |
| std::string name, std::string value) { | |
| return StartsWith<BoundReference>(Ref(std::move(name)), std::move(value)); | |
| } | |
| std::shared_ptr<UnboundPredicateImpl<BoundReference>> Expressions::NotStartsWith( | |
| std::string name, std::string value) { | |
| return NotStartsWith<BoundReference>(Ref(std::move(name)), std::move(value)); | |
| } | |
| // Template implementations for set predicates | |
| std::shared_ptr<UnboundPredicateImpl<BoundReference>> Expressions::In( | |
| std::string name, std::vector<Literal> values) { | |
| return In<BoundReference>(Ref(std::move(name)), std::move(values)); | |
| } | |
| std::shared_ptr<UnboundPredicateImpl<BoundReference>> Expressions::In( | |
| std::string name, std::initializer_list<Literal> values) { | |
| return In<BoundReference>(Ref(std::move(name)), std::vector<Literal>(values)); | |
| } | |
| std::shared_ptr<UnboundPredicateImpl<BoundReference>> Expressions::NotIn( | |
| std::string name, std::vector<Literal> values) { | |
| return NotIn<BoundReference>(Ref(std::move(name)), std::move(values)); | |
| } | |
| std::shared_ptr<UnboundPredicateImpl<BoundReference>> Expressions::NotIn( | |
| std::string name, std::initializer_list<Literal> values) { | |
| return NotIn<BoundReference>(Ref(std::move(name)), std::vector<Literal>(values)); | |
| } | |
| // Template implementations for generic predicate factory | |
| std::shared_ptr<UnboundPredicateImpl<BoundReference>> Expressions::Predicate( | |
| Expression::Operation op, std::string name, Literal value) { | |
| ICEBERG_ASSIGN_OR_THROW(auto pred, UnboundPredicateImpl<BoundReference>::Make( | |
| op, Ref(std::move(name)), std::move(value))); | |
| return pred; | |
| } | |
| std::shared_ptr<UnboundPredicateImpl<BoundReference>> Expressions::Predicate( | |
| Expression::Operation op, std::string name, std::vector<Literal> values) { | |
| ICEBERG_ASSIGN_OR_THROW(auto pred, UnboundPredicateImpl<BoundReference>::Make( | |
| op, Ref(std::move(name)), std::move(values))); | |
| return pred; | |
| } | |
| std::shared_ptr<UnboundPredicateImpl<BoundReference>> Expressions::Predicate( | |
| Expression::Operation op, std::string name, std::initializer_list<Literal> values) { | |
| return Predicate(op, name, std::vector<Literal>(values)); | |
| } | |
| std::shared_ptr<UnboundPredicateImpl<BoundReference>> Expressions::Predicate( | |
| Expression::Operation op, std::string name) { | |
| ICEBERG_ASSIGN_OR_THROW( | |
| auto pred, UnboundPredicateImpl<BoundReference>::Make(op, Ref(std::move(name)))); | |
| return pred; | |
| } | |
| // Constants | |
| std::shared_ptr<True> Expressions::AlwaysTrue() { return True::Instance(); } | |
| std::shared_ptr<False> Expressions::AlwaysFalse() { return False::Instance(); } | |
| // Utilities | |
| std::shared_ptr<NamedReference> Expressions::Ref(std::string name) { | |
| ICEBERG_ASSIGN_OR_THROW(auto ref, NamedReference::Make(std::move(name))); | |
| return ref; | |
| } | |
| Literal Expressions::Lit(Literal::Value value, std::shared_ptr<PrimitiveType> type) { | |
| throw ExpressionError("Literal creation is not implemented"); | |
| } | |
| } // namespace iceberg |