Skip to content

Commit

Permalink
add operator and plan modules
Browse files Browse the repository at this point in the history
  • Loading branch information
connortsui20 committed Jan 25, 2025
1 parent 99edabe commit 704e7a6
Show file tree
Hide file tree
Showing 9 changed files with 285 additions and 0 deletions.
3 changes: 3 additions & 0 deletions optd-types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@

mod expression;
mod memo;
mod operator;
mod plan;

/// TODO make distinction between relational groups and scalar groups.
pub struct GroupId(u64);

/// TODO Add docs.
pub struct LogicalExprId(u64);

/// TODO Add docs.
pub struct PhysicalExprId(u64);
41 changes: 41 additions & 0 deletions optd-types/src/operator/logical.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
use super::Children;

/// A type representing a logical operator in an input logical query plan.
///
/// Each variant of `LogicalOperator` represents a specific kind of logical operator. The current
/// supported operators are `Scan`, `Filter`, and `Join`.
///
/// This type is generic over a `Link` type, which specifies what kind of children this operator is
/// allowed to have in whatever kind of plan it is contained in. This makes it possible to reuse the
/// `LogicalOperator` type in differnt kinds of trees.
///
/// For example, `LogicalOperator` is a valid operator in [`LogicalPlan`], [`PhysicalPlan`],
/// [`PartialLogicalPlan`], and [`PartialPhysicalPlan`].
///
/// [`LogicalPlan`]: crate::plan::logical_plan::LogicalPlan
/// [`PhysicalPlan`]: crate::plan::physical_plan::PhysicalPlan
/// [`PartialLogicalPlan`]: crate::plan::partial_logical_plan::PartialLogicalPlan
/// [`PartialPhysicalPlan`]: crate::plan::partial_physical_plan::PartialPhysicalPlan
pub enum LogicalOperator<Link> {
Scan(LogicalScanOperator<Link>),
Filter(LogicalFilterOperator<Link>),
Join(LogicalJoinOperator<Link>),
}

/// TODO Add docs.
pub struct LogicalScanOperator<Link> {
stuff: (),
children: Children<Link>,
}

/// TODO Add docs.
pub struct LogicalFilterOperator<Link> {
stuff: (),
children: Children<Link>,
}

/// TODO Add docs.
pub struct LogicalJoinOperator<Link> {
stuff: (),
children: Children<Link>,
}
16 changes: 16 additions & 0 deletions optd-types/src/operator/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
use std::sync::Arc;

pub mod logical;
pub mod physical;

/// TODO potentially use the `smallvec` crate here instead.
pub struct Children<T>(Vec<Arc<T>>);

/// Note: This type is generic over `Link` which specifies what kind of children this operator is
/// allowed to have.
///
/// TODO figure out fields.
pub struct ScalarOperator<Link> {
stuff: (),
children: Children<Link>,
}
42 changes: 42 additions & 0 deletions optd-types/src/operator/physical.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
use super::Children;

/// A type representing a physical operator in an output physical query execution plan.
///
/// Each variant of `PhysicalOperator` represents a specific kind of logical operator. The current
/// supported operators are `TableScan`, `PhysicalFilter`, and `HashJoin`.
///
/// This type is generic over a `Link` type, which specifies what kind of children this operator is
/// allowed to have in whatever kind of plan it is contained in. This makes it possible to reuse the
/// `PhysicalOperator` type in differnt kinds of trees.
///
/// For example, `PhysicalOperator` _**is**_ a valid operator in [`PhysicalPlan`] and
/// [`PartialPhysicalPlan`], _**but it is not a valid operator in**_ [`LogicalPlan`] nor
/// [`PartialLogicalPlan`].
///
/// [`LogicalPlan`]: crate::plan::logical_plan::LogicalPlan
/// [`PhysicalPlan`]: crate::plan::physical_plan::PhysicalPlan
/// [`PartialLogicalPlan`]: crate::plan::partial_logical_plan::PartialLogicalPlan
/// [`PartialPhysicalPlan`]: crate::plan::partial_physical_plan::PartialPhysicalPlan
pub enum PhysicalOperator<Link> {
Scan(TableScanOperator<Link>),
Filter(PhysicalFilterOperator<Link>),
Join(HashJoinOperator<Link>),
}

/// TODO Add docs.
pub struct TableScanOperator<Link> {
stuff: (),
children: Children<Link>,
}

/// TODO Add docs.
pub struct PhysicalFilterOperator<Link> {
stuff: (),
children: Children<Link>,
}

/// TODO Add docs.
pub struct HashJoinOperator<Link> {
stuff: (),
children: Children<Link>,
}
56 changes: 56 additions & 0 deletions optd-types/src/plan/logical_plan.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
use crate::operator::{logical::LogicalOperator, ScalarOperator};
use std::sync::Arc;

/// A representation of a logical query plan DAG (directed acyclic graph).
///
/// The `LogicalPlan` DAG consists of [`LogicalOperator<LogicalLink>`] and
/// [`ScalarOperator<ScalarLink>`] nodes, where the generic links denote the kinds of children each
/// of those operators are allowed to have. For example, logical operators are allowed to have both
/// logical and scalar operators as children, but scalar operators are only allowed to have other
/// scalar operators as children.
///
/// The root of the plan DAG _cannot_ be a scalar operator (and thus for now can only be a logical
/// operator).
pub enum LogicalPlan {
LogicalRoot(LogicalOperator<LogicalLink>),
}

/// A link in a [`LogicalPlan`] to a node.
///
/// A `LogicalLink` can either be a `LogicalNode` that points to a `LogicalOperator` or a
/// `ScalarNode` that points to a `ScalarOperator`.
///
/// Note that this `LogicalLink` is _**different**_ from the `LogicalLink`s defined in the sibling
/// modules:
///
/// - [`super::logical_plan::LogicalLink`] only allows a logical operator to have other logical
/// operators or scalar operators as children since that is all [`LogicalPlan`] needs
/// - [`super::physical_plan::LogicalLink`] allows a logical operator to also have a physical
/// operator as a child (since [`PhysicalPlan`] needs to encode both logical and physical
/// operators).
/// - [`super::partial_logical_plan::LogicalLink`] allows a logical operator to also have a
/// [`GroupId`] as a child (since the [`PartialLogicalPlan`] is a partially materialized query
/// plan).
/// - [`super::partial_physical_plan::LogicalLink`] allows a logical operator to have both physical
/// operators _and_ [`GroupId`] as a child (since [`PartialPhysicalPlan`] needs everything).
///
/// [`GroupId`]: crate::GroupId
/// [`LogicalPlan`]: crate::plan::logical_plan::LogicalPlan
/// [`PhysicalPlan`]: crate::plan::physical_plan::PhysicalPlan
/// [`PartialLogicalPlan`]: crate::plan::partial_logical_plan::PartialLogicalPlan
/// [`PartialPhysicalPlan`]: crate::plan::partial_physical_plan::PartialPhysicalPlan
pub enum LogicalLink {
LogicalNode(LogicalOperator<LogicalLink>),
ScalarNode(ScalarOperator<ScalarLink>),
}

/// A link in a [`LogicalPlan`] to a scalar node. A `ScalarLink` can only be a `ScalarNode` that
/// points to a `ScalarOperator` (for now).
///
/// Note that this `ScalarLink` is _**different**_ from the `ScalarLink`s defined in the sibling
/// modules.
///
/// TODO Add detailed docs here.
pub enum ScalarLink {
ScalarNode(ScalarOperator<ScalarLink>),
}
6 changes: 6 additions & 0 deletions optd-types/src/plan/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
use std::sync::Arc;

pub mod logical_plan;
pub mod partial_logical_plan;
pub mod partial_physical_plan;
pub mod physical_plan;
64 changes: 64 additions & 0 deletions optd-types/src/plan/partial_logical_plan.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
use crate::operator::{logical::LogicalOperator, ScalarOperator};
use crate::GroupId;
use std::sync::Arc;

/// A representation of a partially materialized logical query plan DAG.
///
/// Similar to a [`LogicalPlan`], the `PartialLogicalPlan` DAG consists of both logical and scalar
/// operator nodes, but it can also have unmaterialized [`GroupId`]s representing entire memo groups
/// as children.
///
/// Note that while logical nodes can have both logical and scalar nodes as children, scalar nodes can only have other scalar
/// nodes as children.
///
/// Note that the root of the plan _cannot_ be a scalar operator (and thus can only be a logical
/// operator).
///
/// [`LogicalPlan`]: crate::plan::logical_plan::LogicalPlan
pub enum PartialLogicalPlan {
LogicalRoot(LogicalOperator<LogicalLink>),
}

/// A link in a [`PartialLogicalPlan`] to a node.
///
///
/// A `LogicalLink` can be one of three things: it can be a `LogicalNode` that points to a
/// `LogicalOperator`, it can be a `ScalarNode` that points to a `ScalarOperator`, or it can be a
/// [`GroupId`], denoting the unamterialized part of the plan (thus the name `PartialLogicalPlan`).
///
/// Note that this `LogicalLink` is _**different**_ from the `LogicalLink`s defined in the sibling
/// modules:
///
/// - [`super::logical_plan::LogicalLink`] only allows a logical operator to have other logical
/// operators or scalar operators as children since that is all [`LogicalPlan`] needs
/// - [`super::physical_plan::LogicalLink`] allows a logical operator to also have a physical
/// operator as a child (since [`PhysicalPlan`] needs to encode both logical and physical
/// operators).
/// - [`super::partial_logical_plan::LogicalLink`] allows a logical operator to also have a
/// [`GroupId`] as a child (since the [`PartialLogicalPlan`] is a partially materialized query
/// plan).
/// - [`super::partial_physical_plan::LogicalLink`] allows a logical operator to have both physical
/// operators _and_ [`GroupId`] as a child (since [`PartialPhysicalPlan`] needs everything).
///
/// [`GroupId`]: crate::GroupId
/// [`LogicalPlan`]: crate::plan::logical_plan::LogicalPlan
/// [`PhysicalPlan`]: crate::plan::physical_plan::PhysicalPlan
/// [`PartialLogicalPlan`]: crate::plan::partial_logical_plan::PartialLogicalPlan
/// [`PartialPhysicalPlan`]: crate::plan::partial_physical_plan::PartialPhysicalPlan
pub enum LogicalLink {
LogicalNode(LogicalOperator<LogicalLink>),
ScalarNode(ScalarOperator<ScalarLink>),
Group(GroupId),
}

/// A link in a [`LogicalPlan`] to a scalar node. A `ScalarLink` can be either a `ScalarNode` that
/// points to a `ScalarOperator` or a `GroupId`.
///
/// Note that this `ScalarLink` is _**different**_ from the `ScalarLink`s defined in the sibling
/// modules.
///
/// TODO Add detailed docs here.
pub enum ScalarLink {
ScalarNode(ScalarOperator<ScalarLink>),
Group(GroupId),
}
30 changes: 30 additions & 0 deletions optd-types/src/plan/partial_physical_plan.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
use crate::operator::{logical::LogicalOperator, physical::PhysicalOperator, ScalarOperator};
use crate::GroupId;
use std::sync::Arc;

/// TODO Add docs.
pub enum PartialPhysicalPlan {
LogicalRoot(LogicalLink),
PhysicalRoot(PhysicalLink),
}

/// TODO Add docs.
pub enum LogicalLink {
LogicalNode(LogicalOperator<LogicalLink>),
PhysicalNode(PhysicalOperator<PhysicalLink>),
ScalarNode(ScalarOperator<ScalarLink>),
Group(GroupId),
}

/// TODO Add docs.
pub enum PhysicalLink {
PhysicalNode(PhysicalOperator<PhysicalLink>),
ScalarNode(ScalarOperator<ScalarLink>),
Group(GroupId),
}

/// TODO Add docs.
pub enum ScalarLink {
ScalarNode(ScalarOperator<ScalarLink>),
Group(GroupId),
}
27 changes: 27 additions & 0 deletions optd-types/src/plan/physical_plan.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use crate::operator::{logical::LogicalOperator, physical::PhysicalOperator, ScalarOperator};
use std::sync::Arc;

/// TODO Add docs.
pub enum PhysicalPlan {
LogicalRoot(LogicalLink),
PhysicalRoot(PhysicalLink),
}

/// TODO Add docs.
#[allow(clippy::enum_variant_names)]
pub enum LogicalLink {
LogicalNode(LogicalOperator<LogicalLink>),
PhysicalNode(PhysicalOperator<PhysicalLink>),
ScalarNode(ScalarOperator<ScalarLink>),
}

/// TODO Add docs.
pub enum PhysicalLink {
PhysicalNode(PhysicalOperator<PhysicalLink>),
ScalarNode(ScalarOperator<ScalarLink>),
}

/// TODO Add docs.
pub enum ScalarLink {
ScalarNode(ScalarOperator<ScalarLink>),
}

0 comments on commit 704e7a6

Please sign in to comment.