linkrs_query/planning/statements/dml/
assignment_planner.rs1use crate::parser::ast::stmt::{AssignmentStmt, Stmt};
7use crate::planning::plan::SubPlan;
8use crate::planning::planner::{Planner, PlannerEnum, PlannerError, ValidatedStatement};
9use crate::QueryContext;
10use std::sync::Arc;
11
12#[derive(Debug, Clone)]
17pub struct AssignmentPlanner;
18
19impl AssignmentPlanner {
20 pub fn new() -> Self {
21 Self
22 }
23
24 fn extract_assignment_stmt<'a>(
25 &self,
26 stmt: &'a Stmt,
27 ) -> Result<&'a AssignmentStmt, PlannerError> {
28 match stmt {
29 Stmt::Assignment(assignment_stmt) => Ok(assignment_stmt),
30 _ => Err(PlannerError::PlanGenerationFailed(
31 "statement does not contain the Assignment".to_string(),
32 )),
33 }
34 }
35}
36
37impl Planner for AssignmentPlanner {
38 fn plan_bound(
39 &mut self,
40 ctx: &crate::planning::context::PlanContext<'_>,
41 ) -> Result<SubPlan, PlannerError> {
42 let bound = ctx.bound;
43 let qctx = ctx.qctx.clone();
44 let metadata = ctx.metadata;
45 let validated = ctx.validated;
46 let assignment = match bound {
47 crate::binder::BoundStatement::Assignment(a) => a,
48 _ => return self.transform(validated, qctx),
50 };
51
52 let mut inner_planner = PlannerEnum::from_bound_statement(&assignment.statement)
53 .ok_or_else(|| {
54 PlannerError::NoSuitablePlanner(format!(
55 "assignment inner statement: {}",
56 assignment.statement.kind()
57 ))
58 })?;
59
60 let inner_validated = ctx.derive_validated(&assignment.statement);
61 let inner_ctx = crate::planning::context::PlanContext {
62 bound: &assignment.statement,
63 qctx: qctx.clone(),
64 metadata,
65 validated: inner_validated.as_ref().unwrap_or(validated),
66 };
67 let inner_plan = inner_planner.plan_bound(&inner_ctx)?;
68
69 log::debug!(
70 "AssignmentPlanner: variable '{}' bound to inner plan",
71 assignment.variable
72 );
73
74 Ok(inner_plan)
75 }
76
77 fn transform(
78 &mut self,
79 validated: &ValidatedStatement,
80 qctx: Arc<QueryContext>,
81 ) -> Result<SubPlan, PlannerError> {
82 let assignment_stmt = self.extract_assignment_stmt(validated.stmt())?;
83
84 let inner_validated = ValidatedStatement::new(
85 Arc::new(crate::parser::ast::stmt::Ast::new(
86 (*assignment_stmt.statement).clone(),
87 validated.ast.expr_context().clone(),
88 )),
89 validated.validation_info.clone(),
90 );
91
92 let mut inner_planner =
93 PlannerEnum::from_stmt_ref(inner_validated.stmt()).ok_or_else(|| {
94 PlannerError::NoSuitablePlanner(format!(
95 "assignment inner statement: {}",
96 assignment_stmt.statement.kind()
97 ))
98 })?;
99
100 let inner_plan = inner_planner.transform(&inner_validated, qctx)?;
101
102 log::debug!(
103 "AssignmentPlanner: variable '{}' bound to inner plan",
104 assignment_stmt.variable
105 );
106
107 Ok(inner_plan)
108 }
109
110 fn match_planner(&self, stmt: &Stmt) -> bool {
111 matches!(stmt, Stmt::Assignment(_))
112 }
113}
114
115impl Default for AssignmentPlanner {
116 fn default() -> Self {
117 Self::new()
118 }
119}