#pragma once
#include "logical_operator_visitor.h"
#include "planner/operator/logical_plan.h"
namespace lbug {
namespace binder {
class Expression;
class NodeExpression;
class RelExpression;
} namespace main {
class ClientContext;
}
namespace optimizer {
class CountRelTableOptimizer : public LogicalOperatorVisitor {
public:
explicit CountRelTableOptimizer(main::ClientContext* context) : _context{context} {}
void rewrite(planner::LogicalPlan* plan);
private:
std::shared_ptr<planner::LogicalOperator> visitOperator(
const std::shared_ptr<planner::LogicalOperator>& op);
std::shared_ptr<planner::LogicalOperator> visitAggregateReplace(
std::shared_ptr<planner::LogicalOperator> op) override;
std::shared_ptr<planner::LogicalOperator> visitOrderByReplace(
std::shared_ptr<planner::LogicalOperator> op) override;
bool isSimpleCount(planner::LogicalOperator* op) const;
bool isCountStar(planner::LogicalOperator* op) const;
bool isCountRelID(planner::LogicalOperator* op, const binder::RelExpression& rel) const;
bool isDistinctCountNodeKey(planner::LogicalOperator* op,
const std::shared_ptr<binder::Expression>& nodeKey) const;
bool isCountNbr(planner::LogicalOperator* op, const binder::NodeExpression& nbr) const;
bool isRelIDExpression(const std::shared_ptr<binder::Expression>& expression,
const binder::RelExpression& rel) const;
bool canOptimize(planner::LogicalOperator* aggregate) const;
std::shared_ptr<planner::LogicalOperator> tryRewriteActiveBoundCount(
std::shared_ptr<planner::LogicalOperator> op);
std::shared_ptr<planner::LogicalOperator> tryRewriteDegreeTopK(
std::shared_ptr<planner::LogicalOperator> op);
[[maybe_unused]] main::ClientContext* _context;
};
} }