Skip to content

Commit

Permalink
feat: Expression system. (#132)
Browse files Browse the repository at this point in the history
* feat: Expressions

* Fix comments

* Refactor expression to be more similar to iceberg model

* Fix typo
  • Loading branch information
liurenjie1024 committed Dec 26, 2023
1 parent 6a401d4 commit 6375fb8
Show file tree
Hide file tree
Showing 4 changed files with 175 additions and 0 deletions.
42 changes: 42 additions & 0 deletions crates/iceberg/src/expr/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// 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.

//! This module contains expressions.

mod term;
pub use term::*;
mod predicate;
pub use predicate::*;

/// Predicate operators used in expressions.
#[allow(missing_docs)]
pub enum PredicateOperator {
IsNull,
NotNull,
IsNan,
NotNan,
LessThan,
LessThanOrEq,
GreaterThan,
GreaterThanOrEq,
Eq,
NotEq,
In,
NotIn,
StartsWith,
NotStartsWith,
}
93 changes: 93 additions & 0 deletions crates/iceberg/src/expr/predicate.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// 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.

//! This module contains predicate expressions.
//! Predicate expressions are used to filter data, and evaluates to a boolean value. For example,
//! `a > 10` is a predicate expression, and it evaluates to `true` if `a` is greater than `10`,

use crate::expr::{BoundReference, PredicateOperator, UnboundReference};
use crate::spec::Literal;
use std::collections::HashSet;

/// Logical expression, such as `AND`, `OR`, `NOT`.
pub struct LogicalExpression<T, const N: usize> {
inputs: [Box<T>; N],
}

/// Unary predicate, for example, `a IS NULL`.
pub struct UnaryExpression<T> {
/// Operator of this predicate, must be single operand operator.
op: PredicateOperator,
/// Term of this predicate, for example, `a` in `a IS NULL`.
term: T,
}

/// Binary predicate, for example, `a > 10`.
pub struct BinaryExpression<T> {
/// Operator of this predicate, must be binary operator, such as `=`, `>`, `<`, etc.
op: PredicateOperator,
/// Term of this predicate, for example, `a` in `a > 10`.
term: T,
/// Literal of this predicate, for example, `10` in `a > 10`.
literal: Literal,
}

/// Set predicates, for example, `a in (1, 2, 3)`.
pub struct SetExpression<T> {
/// Operator of this predicate, must be set operator, such as `IN`, `NOT IN`, etc.
op: PredicateOperator,
/// Term of this predicate, for example, `a` in `a in (1, 2, 3)`.
term: T,
/// Literals of this predicate, for example, `(1, 2, 3)` in `a in (1, 2, 3)`.
literals: HashSet<Literal>,
}

/// Unbound predicate expression before binding to a schema.
pub enum UnboundPredicate {
/// And predicate, for example, `a > 10 AND b < 20`.
And(LogicalExpression<UnboundPredicate, 2>),
/// Or predicate, for example, `a > 10 OR b < 20`.
Or(LogicalExpression<UnboundPredicate, 2>),
/// Not predicate, for example, `NOT (a > 10)`.
Not(LogicalExpression<UnboundPredicate, 1>),
/// Unary expression, for example, `a IS NULL`.
Unary(UnaryExpression<UnboundReference>),
/// Binary expression, for example, `a > 10`.
Binary(BinaryExpression<UnboundReference>),
/// Set predicates, for example, `a in (1, 2, 3)`.
Set(SetExpression<UnboundReference>),
}

/// Bound predicate expression after binding to a schema.
pub enum BoundPredicate {
/// An expression always evaluates to true.
AlwaysTrue,
/// An expression always evaluates to false.
AlwaysFalse,
/// An expression combined by `AND`, for example, `a > 10 AND b < 20`.
And(LogicalExpression<BoundPredicate, 2>),
/// An expression combined by `OR`, for example, `a > 10 OR b < 20`.
Or(LogicalExpression<BoundPredicate, 2>),
/// An expression combined by `NOT`, for example, `NOT (a > 10)`.
Not(LogicalExpression<BoundPredicate, 1>),
/// Unary expression, for example, `a IS NULL`.
Unary(UnaryExpression<BoundReference>),
/// Binary expression, for example, `a > 10`.
Binary(BinaryExpression<BoundReference>),
/// Set predicates, for example, `a in (1, 2, 3)`.
Set(SetExpression<BoundReference>),
}
37 changes: 37 additions & 0 deletions crates/iceberg/src/expr/term.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// 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.

//! Term definition.

use crate::spec::NestedFieldRef;

/// Unbound term before binding to a schema.
pub type UnboundTerm = UnboundReference;

/// A named reference in an unbound expression.
/// For example, `a` in `a > 10`.
pub struct UnboundReference {
name: String,
}

/// A named reference in a bound expression after binding to a schema.
pub struct BoundReference {
field: NestedFieldRef,
}

/// Bound term after binding to a schema.
pub type BoundTerm = BoundReference;
3 changes: 3 additions & 0 deletions crates/iceberg/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ pub use error::ErrorKind;
pub use error::Result;

mod catalog;

pub use catalog::Catalog;
pub use catalog::Namespace;
pub use catalog::NamespaceIdent;
Expand All @@ -44,5 +45,7 @@ mod avro;
pub mod io;
pub mod spec;

#[allow(dead_code)]
pub mod expr;
pub mod transaction;
pub mod transform;

0 comments on commit 6375fb8

Please sign in to comment.