use crate::ir::*;
use crate::types::*;
#[derive(Debug)]
pub struct LogicalPlanner;
impl LogicalPlanner {
pub fn new() -> Self {
Self
}
pub fn parse_gql(&self, gql: &str) -> Result<PlanIR> {
if gql.trim().to_lowercase().starts_with("match") {
self.parse_match_query(gql)
} else {
Err(KotobaError::Parse(format!("Unsupported GQL query: {}", gql)))
}
}
fn parse_match_query(&self, _gql: &str) -> Result<PlanIR> {
let plan = LogicalOp::NodeScan {
label: "Person".to_string(),
as_: "n".to_string(),
props: None,
};
Ok(PlanIR {
plan,
limit: Some(100),
})
}
pub fn optimize(&self, plan: &PlanIR, _catalog: &Catalog) -> PlanIR {
plan.clone()
}
}
#[derive(Debug)]
pub struct CostEstimator;
impl CostEstimator {
pub fn new() -> Self {
Self
}
pub fn estimate_cost(&self, op: &LogicalOp, catalog: &Catalog) -> f64 {
match op {
LogicalOp::NodeScan { label, .. } => {
catalog.get_label(label)
.map(|_| 100.0) .unwrap_or(1000.0)
}
LogicalOp::Expand { .. } => 50.0,
LogicalOp::Filter { .. } => 10.0,
LogicalOp::Join { .. } => 200.0,
LogicalOp::Project { .. } => 5.0,
LogicalOp::Sort { .. } => 100.0,
LogicalOp::Limit { .. } => 1.0,
LogicalOp::Distinct { .. } => 50.0,
LogicalOp::IndexScan { .. } => 10.0,
LogicalOp::Group { .. } => 150.0,
}
}
}