kotoba_execution/planner/
logical.rs1use kotoba_core::ir::*;
4use kotoba_core::types::*;
5use kotoba_errors::KotobaError;
6use std::collections::HashMap;
7
8#[derive(Debug)]
10pub struct LogicalPlanner;
11
12impl LogicalPlanner {
13 pub fn new() -> Self {
14 Self
15 }
16
17 pub fn parse_gql(&self, gql: &str) -> Result<PlanIR> {
19 if gql.trim().to_lowercase().starts_with("match") {
23 self.parse_match_query(gql)
24 } else {
25 Err(KotobaError::Parse(format!("Unsupported GQL query: {}", gql)))
26 }
27 }
28
29 fn parse_match_query(&self, _gql: &str) -> Result<PlanIR> {
31 let plan = LogicalOp::NodeScan {
35 label: "Person".to_string(),
36 as_: "n".to_string(),
37 props: None,
38 };
39
40 Ok(PlanIR {
41 plan,
42 limit: Some(100),
43 })
44 }
45
46 pub fn optimize(&self, plan: &PlanIR, _catalog: &Catalog) -> PlanIR {
48 plan.clone()
52 }
53}
54
55#[derive(Debug)]
57pub struct CostEstimator;
58
59impl CostEstimator {
60 pub fn new() -> Self {
61 Self
62 }
63
64 pub fn estimate_cost(&self, op: &LogicalOp, catalog: &Catalog) -> f64 {
66 match op {
67 LogicalOp::NodeScan { label, .. } => {
68 catalog.get_label(label)
70 .map(|_| 100.0) .unwrap_or(1000.0)
72 }
73 LogicalOp::Expand { .. } => 50.0,
74 LogicalOp::Filter { .. } => 10.0,
75 LogicalOp::Join { .. } => 200.0,
76 LogicalOp::Project { .. } => 5.0,
77 LogicalOp::Sort { .. } => 100.0,
78 LogicalOp::Limit { .. } => 1.0,
79 LogicalOp::Distinct { .. } => 50.0,
80 LogicalOp::IndexScan { .. } => 10.0,
81 LogicalOp::Group { .. } => 150.0,
82 }
83 }
84}