#pragma once
#include "binder/expression/node_expression.h"
namespace lbug {
namespace planner {
enum class TreeNodeType : uint8_t {
NODE_SCAN = 0,
REL_SCAN = 1,
BINARY_JOIN = 5,
MULTIWAY_JOIN = 6,
};
struct TreeNodeTypeUtils {
static std::string toString(TreeNodeType type);
};
struct ExtraTreeNodeInfo {
virtual ~ExtraTreeNodeInfo() = default;
virtual std::unique_ptr<ExtraTreeNodeInfo> copy() const = 0;
template<class TARGET>
const TARGET& constCast() const {
return common::dynamic_cast_checked<const TARGET&>(*this);
}
template<class TARGET>
TARGET& cast() {
return common::dynamic_cast_checked<TARGET&>(*this);
}
};
struct ExtraJoinTreeNodeInfo : ExtraTreeNodeInfo {
std::vector<std::shared_ptr<binder::NodeExpression>> joinNodes;
binder::expression_vector predicates;
explicit ExtraJoinTreeNodeInfo(std::shared_ptr<binder::NodeExpression> joinNode) {
joinNodes.push_back(std::move(joinNode));
}
explicit ExtraJoinTreeNodeInfo(std::vector<std::shared_ptr<binder::NodeExpression>> joinNodes)
: joinNodes{std::move(joinNodes)} {}
ExtraJoinTreeNodeInfo(const ExtraJoinTreeNodeInfo& other)
: joinNodes{other.joinNodes}, predicates{other.predicates} {}
std::unique_ptr<ExtraTreeNodeInfo> copy() const override {
return std::make_unique<ExtraJoinTreeNodeInfo>(*this);
}
};
struct NodeRelScanInfo {
std::shared_ptr<binder::Expression> nodeOrRel;
binder::expression_vector properties;
binder::expression_vector predicates;
NodeRelScanInfo(std::shared_ptr<binder::Expression> nodeOrRel,
binder::expression_vector properties)
: nodeOrRel{std::move(nodeOrRel)}, properties{std::move(properties)} {}
};
struct ExtraScanTreeNodeInfo : ExtraTreeNodeInfo {
std::unique_ptr<NodeRelScanInfo> nodeInfo;
std::vector<NodeRelScanInfo> relInfos;
binder::expression_vector predicates;
ExtraScanTreeNodeInfo() = default;
ExtraScanTreeNodeInfo(const ExtraScanTreeNodeInfo& other)
: nodeInfo{std::make_unique<NodeRelScanInfo>(*other.nodeInfo)}, relInfos{other.relInfos} {}
void merge(const ExtraScanTreeNodeInfo& other);
std::unique_ptr<ExtraTreeNodeInfo> copy() const override {
return std::make_unique<ExtraScanTreeNodeInfo>(*this);
}
};
struct JoinTreeNode {
TreeNodeType type;
std::unique_ptr<ExtraTreeNodeInfo> extraInfo;
std::vector<std::shared_ptr<JoinTreeNode>> children;
JoinTreeNode(TreeNodeType type, std::unique_ptr<ExtraTreeNodeInfo> extraInfo)
: type{type}, extraInfo{std::move(extraInfo)} {}
DELETE_COPY_DEFAULT_MOVE(JoinTreeNode);
std::string toString() const;
void addChild(std::shared_ptr<JoinTreeNode> child) { children.push_back(std::move(child)); }
};
struct JoinTree {
std::shared_ptr<JoinTreeNode> root;
explicit JoinTree(std::shared_ptr<JoinTreeNode> root) : root{std::move(root)} {}
JoinTree(const JoinTree& other) : root{other.root} {}
};
} }