icydb_core/db/session/sql/surface/
route.rs1use crate::db::{
8 GroupedRow, QueryError,
9 sql::lowering::{
10 LoweredSqlCommand, LoweredSqlLaneKind, PreparedSqlStatement as CorePreparedSqlStatement,
11 lower_sql_command_from_prepared_statement, lowered_sql_command_lane, prepare_sql_statement,
12 },
13 sql::parser::{SqlExplainTarget, SqlStatement},
14};
15
16#[derive(Clone, Debug, Eq, PartialEq)]
21pub enum SqlStatementRoute {
22 Query { entity: String },
23 Explain { entity: String },
24 Describe { entity: String },
25 ShowIndexes { entity: String },
26 ShowColumns { entity: String },
27 ShowEntities,
28}
29
30#[derive(Debug)]
32pub enum SqlDispatchResult {
33 Projection {
34 columns: Vec<String>,
35 rows: Vec<Vec<crate::value::Value>>,
36 row_count: u32,
37 },
38 ProjectionText {
39 columns: Vec<String>,
40 rows: Vec<Vec<String>>,
41 row_count: u32,
42 },
43 Grouped {
44 columns: Vec<String>,
45 rows: Vec<GroupedRow>,
46 row_count: u32,
47 next_cursor: Option<String>,
48 },
49 Explain(String),
50 Describe(crate::db::EntitySchemaDescription),
51 ShowIndexes(Vec<String>),
52 ShowColumns(Vec<crate::db::EntityFieldDescription>),
53 ShowEntities(Vec<String>),
54}
55
56#[derive(Clone, Debug)]
65pub struct SqlParsedStatement {
66 pub(in crate::db::session::sql) statement: SqlStatement,
67 route: SqlStatementRoute,
68}
69
70impl SqlParsedStatement {
71 pub(in crate::db::session::sql) const fn new(
73 statement: SqlStatement,
74 route: SqlStatementRoute,
75 ) -> Self {
76 Self { statement, route }
77 }
78
79 #[must_use]
81 pub const fn route(&self) -> &SqlStatementRoute {
82 &self.route
83 }
84
85 pub(in crate::db::session::sql) fn prepare(
87 &self,
88 expected_entity: &'static str,
89 ) -> Result<CorePreparedSqlStatement, QueryError> {
90 prepare_sql_statement(self.statement.clone(), expected_entity)
91 .map_err(QueryError::from_sql_lowering_error)
92 }
93
94 #[inline(never)]
96 pub fn lower_query_lane_for_entity(
97 &self,
98 expected_entity: &'static str,
99 primary_key_field: &str,
100 ) -> Result<LoweredSqlCommand, QueryError> {
101 let lowered = lower_sql_command_from_prepared_statement(
102 self.prepare(expected_entity)?,
103 primary_key_field,
104 )
105 .map_err(QueryError::from_sql_lowering_error)?;
106 let lane = lowered_sql_command_lane(&lowered);
107
108 match lane {
109 LoweredSqlLaneKind::Query | LoweredSqlLaneKind::Explain => Ok(lowered),
110 LoweredSqlLaneKind::Describe
111 | LoweredSqlLaneKind::ShowIndexes
112 | LoweredSqlLaneKind::ShowColumns
113 | LoweredSqlLaneKind::ShowEntities => {
114 Err(QueryError::unsupported_query_lane_dispatch())
115 }
116 }
117 }
118}
119
120impl SqlStatementRoute {
121 #[must_use]
126 pub const fn entity(&self) -> &str {
127 match self {
128 Self::Query { entity }
129 | Self::Explain { entity }
130 | Self::Describe { entity }
131 | Self::ShowIndexes { entity }
132 | Self::ShowColumns { entity } => entity.as_str(),
133 Self::ShowEntities => "",
134 }
135 }
136
137 #[must_use]
139 pub const fn is_explain(&self) -> bool {
140 matches!(self, Self::Explain { .. })
141 }
142
143 #[must_use]
145 pub const fn is_describe(&self) -> bool {
146 matches!(self, Self::Describe { .. })
147 }
148
149 #[must_use]
151 pub const fn is_show_indexes(&self) -> bool {
152 matches!(self, Self::ShowIndexes { .. })
153 }
154
155 #[must_use]
157 pub const fn is_show_columns(&self) -> bool {
158 matches!(self, Self::ShowColumns { .. })
159 }
160
161 #[must_use]
163 pub const fn is_show_entities(&self) -> bool {
164 matches!(self, Self::ShowEntities)
165 }
166}
167
168pub(in crate::db::session::sql) fn sql_statement_route_from_statement(
170 statement: &SqlStatement,
171) -> SqlStatementRoute {
172 match statement {
173 SqlStatement::Select(select) => SqlStatementRoute::Query {
174 entity: select.entity.clone(),
175 },
176 SqlStatement::Delete(delete) => SqlStatementRoute::Query {
177 entity: delete.entity.clone(),
178 },
179 SqlStatement::Explain(explain) => match &explain.statement {
180 SqlExplainTarget::Select(select) => SqlStatementRoute::Explain {
181 entity: select.entity.clone(),
182 },
183 SqlExplainTarget::Delete(delete) => SqlStatementRoute::Explain {
184 entity: delete.entity.clone(),
185 },
186 },
187 SqlStatement::Describe(describe) => SqlStatementRoute::Describe {
188 entity: describe.entity.clone(),
189 },
190 SqlStatement::ShowIndexes(show_indexes) => SqlStatementRoute::ShowIndexes {
191 entity: show_indexes.entity.clone(),
192 },
193 SqlStatement::ShowColumns(show_columns) => SqlStatementRoute::ShowColumns {
194 entity: show_columns.entity.clone(),
195 },
196 SqlStatement::ShowEntities(_) => SqlStatementRoute::ShowEntities,
197 }
198}