Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/iceberg/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@ set(ICEBERG_SOURCES
statistics_file.cc
table_metadata.cc
transform.cc
type.cc)
type.cc
expressions/true.cc
expressions/false.cc
expressions/and.cc)

set(ICEBERG_STATIC_BUILD_INTERFACE_LIBS)
set(ICEBERG_SHARED_BUILD_INTERFACE_LIBS)
Expand Down
83 changes: 83 additions & 0 deletions src/iceberg/expression.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* 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.
*/

#pragma once

/// \file iceberg/expression.h
/// Expression interface for Iceberg table operations.

#include "iceberg/expected.h"
#include "iceberg/iceberg_export.h"
#include "iceberg/result.h"

namespace iceberg {

/// \brief Represents a boolean expression tree.
class ICEBERG_EXPORT Expression {
public:
/// Operation types for expressions
enum class Operation {
kTrue,
kFalse,
kIsNull,
kNotNull,
kIsNan,
kNotNan,
kLt,
kLtEq,
kGt,
kGtEq,
kEq,
kNotEq,
kIn,
kNotIn,
kNot,
kAnd,
kOr,
kStartsWith,
kNotStartsWith,
kCount,
kCountStar,
kMax,
kMin
};

virtual ~Expression() = default;

/// \brief Returns the operation for an expression node.
virtual Operation Op() const = 0;

/// \brief Returns the negation of this expression, equivalent to not(this).
virtual Result<std::shared_ptr<Expression>> Negate() const {
return unexpected(
Error(ErrorKind::kInvalidExpression, "Expression cannot be negated"));
}

/// \brief Returns whether this expression will accept the same values as another.
/// \param other another expression
/// \return true if the expressions are equivalent
virtual bool IsEquivalentTo(const Expression& other) const {
// only bound predicates can be equivalent
return false;
}

virtual std::string ToString() const { return "Expression"; }
};

} // namespace iceberg
38 changes: 38 additions & 0 deletions src/iceberg/expressions/and.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* 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 "and.h"

namespace iceberg {

And::And(std::shared_ptr<Expression> left, std::shared_ptr<Expression> right)
: left_(std::move(left)), right_(std::move(right)) {}

bool And::IsEquivalentTo(const Expression& expr) const {
if (expr.Op() == Operation::kAnd) {
const auto& other = static_cast<const And&>(expr);
return (left_->IsEquivalentTo(*other.left()) &&
right_->IsEquivalentTo(*other.right())) ||
(left_->IsEquivalentTo(*other.right()) &&
right_->IsEquivalentTo(*other.left()));
}
return false;
}

} // namespace iceberg
68 changes: 68 additions & 0 deletions src/iceberg/expressions/and.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* 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.
*/

#pragma once

#include <format>
#include <memory>
#include <string>

#include "iceberg/expression.h"

namespace iceberg {

/// \brief An Expression that represents a logical AND operation between two expressions.
///
/// This expression evaluates to true if and only if both of its child expressions
/// evaluate to true.
class ICEBERG_EXPORT And : public Expression {
public:
/// \brief Constructs an And expression from two sub-expressions.
///
/// @param left The left operand of the AND expression
/// @param right The right operand of the AND expression
And(std::shared_ptr<Expression> left, std::shared_ptr<Expression> right);

/// \brief Returns the left operand of the AND expression.
///
/// @return The left operand of the AND expression
const std::shared_ptr<Expression>& left() const { return left_; }

/// \brief Returns the right operand of the AND expression.
///
/// @return The right operand of the AND expression
const std::shared_ptr<Expression>& right() const { return right_; }

Operation Op() const override { return Operation::kAnd; }

std::string ToString() const override {
return std::format("({} and {})", left_->ToString(), right_->ToString());
}

// implement Negate later
// expected<std::shared_ptr<Expression>, Error> Negate() const override;

bool IsEquivalentTo(const Expression& other) const override;

private:
std::shared_ptr<Expression> left_;
std::shared_ptr<Expression> right_;
};

} // namespace iceberg
30 changes: 30 additions & 0 deletions src/iceberg/expressions/false.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* 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 "false.h"

#include "true.h"

namespace iceberg {

expected<std::shared_ptr<Expression>, Error> False::Negate() const {
return True::shared_instance();
}

} // namespace iceberg
55 changes: 55 additions & 0 deletions src/iceberg/expressions/false.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* 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.
*/

#pragma once

#include <string>

#include "iceberg/expression.h"

namespace iceberg {

/// \brief An expression that is always false.
class ICEBERG_EXPORT False : public Expression {
public:
static const False& instance() {
static False instance;
return instance;
}

static const std::shared_ptr<Expression>& shared_instance() {
static std::shared_ptr<Expression> instance = std::shared_ptr<Expression>(
const_cast<False*>(&False::instance()), [](Expression*) {});
return instance;
}

Operation Op() const override { return Operation::kFalse; }

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

Result<std::shared_ptr<Expression>> Negate() const override;

bool IsEquivalentTo(const Expression& other) const override {
return other.Op() == Operation::kFalse;
}

private:
constexpr False() = default;
};
} // namespace iceberg
30 changes: 30 additions & 0 deletions src/iceberg/expressions/true.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* 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 "true.h"

#include "false.h"

namespace iceberg {

Result<std::shared_ptr<Expression>> True::Negate() const {
return False::shared_instance();
}

} // namespace iceberg
59 changes: 59 additions & 0 deletions src/iceberg/expressions/true.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* 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.
*/

#pragma once

#include <memory>
#include <string>

#include "iceberg/expression.h"

namespace iceberg {

/// \brief An Expression that is always true.
///
/// Represents a boolean predicate that always evaluates to true.
class ICEBERG_EXPORT True : public Expression {
public:
static const True& instance() {
static True instance;
return instance;
}

static const std::shared_ptr<Expression>& shared_instance() {
static std::shared_ptr<Expression> instance = std::shared_ptr<Expression>(
const_cast<True*>(&True::instance()), [](Expression*) {});
return instance;
}

Operation Op() const override { return Operation::kTrue; }

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

Result<std::shared_ptr<Expression>> Negate() const override;

bool IsEquivalentTo(const Expression& other) const override {
return other.Op() == Operation::kTrue;
}

private:
constexpr True() = default;
};

} // namespace iceberg
2 changes: 2 additions & 0 deletions src/iceberg/result.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ enum class ErrorKind {
kNotImplemented,
kUnknownError,
kNotSupported,
kInvalidExpression,
kInvalidOperatorType,
kJsonParseError,
};

Expand Down
Loading