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