limbo_sqlite3_parser/parser/ast/
check.rs1use crate::ast::*;
3use crate::custom_err;
4use std::fmt::{Display, Formatter};
5
6impl Cmd {
7 pub fn stmt(&self) -> &Stmt {
9 match self {
10 Self::Explain(stmt) => stmt,
11 Self::ExplainQueryPlan(stmt) => stmt,
12 Self::Stmt(stmt) => stmt,
13 }
14 }
15 pub fn column_count(&self) -> ColumnCount {
17 match self {
18 Self::Explain(_) => ColumnCount::Fixed(8),
19 Self::ExplainQueryPlan(_) => ColumnCount::Fixed(4),
20 Self::Stmt(stmt) => stmt.column_count(),
21 }
22 }
23 pub fn is_explain(&self) -> bool {
25 matches!(self, Self::Explain(_) | Self::ExplainQueryPlan(_))
26 }
27 pub fn readonly(&self) -> bool {
29 self.stmt().readonly()
30 }
31 pub fn check(&self) -> Result<(), ParserError> {
33 self.stmt().check()
34 }
35}
36
37pub enum ColumnCount {
39 Dynamic,
41 Fixed(usize),
43 None,
45}
46
47impl ColumnCount {
48 fn incr(&mut self) {
49 if let Self::Fixed(n) = self {
50 *n += 1;
51 }
52 }
53}
54
55impl Stmt {
56 pub fn column_count(&self) -> ColumnCount {
58 match self {
59 Self::Delete(delete) => {
60 let Delete { returning, .. } = &**delete;
61 match returning {
62 Some(returning) => column_count(returning),
63 None => ColumnCount::None,
64 }
65 }
66 Self::Insert(insert) => {
67 let Insert { returning, .. } = &**insert;
68 match returning {
69 Some(returning) => column_count(returning),
70 None => ColumnCount::None,
71 }
72 }
73 Self::Pragma(..) => ColumnCount::Dynamic,
74 Self::Select(s) => s.column_count(),
75 Self::Update(update) => {
76 let Update { returning, .. } = &**update;
77 match returning {
78 Some(returning) => column_count(returning),
79 None => ColumnCount::None,
80 }
81 }
82 _ => ColumnCount::None,
83 }
84 }
85
86 pub fn readonly(&self) -> bool {
88 match self {
89 Self::Attach { .. } => true,
90 Self::Begin(..) => true,
91 Self::Commit(..) => true,
92 Self::Detach(..) => true,
93 Self::Pragma(..) => true, Self::Reindex { .. } => true,
95 Self::Release(..) => true,
96 Self::Rollback { .. } => true,
97 Self::Savepoint(..) => true,
98 Self::Select(..) => true,
99 _ => false,
100 }
101 }
102
103 pub fn check(&self) -> Result<(), ParserError> {
105 match self {
106 Self::AlterTable(alter_table) => {
107 let (_, body) = &**alter_table;
108 match body {
109 AlterTableBody::AddColumn(cd) => {
110 for c in cd {
111 if let ColumnConstraint::PrimaryKey { .. } = c {
112 return Err(custom_err!("Cannot add a PRIMARY KEY column"));
113 }
114 if let ColumnConstraint::Unique(..) = c {
115 return Err(custom_err!("Cannot add a UNIQUE column"));
116 }
117 }
118 }
119 _ => {}
120 }
121 Ok(())
122 }
123 Self::CreateTable {
124 temporary,
125 tbl_name,
126 body,
127 ..
128 } => {
129 if *temporary {
130 if let Some(ref db_name) = tbl_name.db_name {
131 if db_name != "TEMP" {
132 return Err(custom_err!("temporary table name must be unqualified"));
133 }
134 }
135 }
136 body.check(tbl_name)
137 }
138 Self::CreateView {
139 view_name,
140 columns: Some(columns),
141 select,
142 ..
143 } => {
144 for (i, c) in columns.iter().enumerate() {
146 for o in &columns[i + 1..] {
147 if c.col_name == o.col_name {
148 return Err(custom_err!("duplicate column name: {}", c.col_name,));
149 }
150 }
151 }
152 match select.column_count() {
154 ColumnCount::Fixed(n) if n != columns.len() => Err(custom_err!(
155 "expected {} columns for {} but got {}",
156 columns.len(),
157 view_name,
158 n
159 )),
160 _ => Ok(()),
161 }
162 }
163 Self::Delete(delete) => {
164 let Delete {
165 order_by, limit, ..
166 } = &**delete;
167 if let Some(_) = order_by {
168 if limit.is_none() {
169 return Err(custom_err!("ORDER BY without LIMIT on DELETE"));
170 }
171 }
172 Ok(())
173 }
174 Self::Insert(insert) => {
175 let Insert { columns, body, .. } = &**insert;
176 if columns.is_none() {
177 return Ok(());
178 }
179 let columns = columns
180 .as_ref()
181 .expect("columns is Some after is_none() guard above");
182 match &*body {
183 InsertBody::Select(select, ..) => match select.body.select.column_count() {
184 ColumnCount::Fixed(n) if n != columns.len() => {
185 Err(custom_err!("{} values for {} columns", n, columns.len()))
186 }
187 _ => Ok(()),
188 },
189 InsertBody::DefaultValues => {
190 Err(custom_err!("0 values for {} columns", columns.len()))
191 }
192 }
193 }
194 Self::Update(update) => {
195 let Update {
196 order_by, limit, ..
197 } = &**update;
198 if let Some(_) = order_by {
199 if limit.is_none() {
200 return Err(custom_err!("ORDER BY without LIMIT on UPDATE"));
201 }
202 }
203
204 Ok(())
205 }
206 _ => Ok(()),
207 }
208 }
209}
210
211impl CreateTableBody {
212 pub fn check(&self, tbl_name: &QualifiedName) -> Result<(), ParserError> {
214 if let Self::ColumnsAndConstraints {
215 columns,
216 constraints: _,
217 options,
218 } = self
219 {
220 let mut generated_count = 0;
221 for c in columns.values() {
222 if c.col_name == "rowid" {
223 return Err(custom_err!("cannot use reserved word: ROWID"));
224 }
225 for cs in &c.constraints {
226 if let ColumnConstraint::Generated { .. } = cs.constraint {
227 generated_count += 1;
228 }
229 }
230 }
231 if generated_count == columns.len() {
232 return Err(custom_err!("must have at least one non-generated column"));
233 }
234
235 if options.contains(TableOptions::STRICT) {
236 for c in columns.values() {
237 match &c.col_type {
238 Some(Type { name, .. }) => {
239 if !(name.eq_ignore_ascii_case("INT")
241 || name.eq_ignore_ascii_case("INTEGER")
242 || name.eq_ignore_ascii_case("REAL")
243 || name.eq_ignore_ascii_case("TEXT")
244 || name.eq_ignore_ascii_case("BLOB")
245 || name.eq_ignore_ascii_case("ANY"))
246 {
247 return Err(custom_err!(
248 "unknown datatype for {}.{}: \"{}\"",
249 tbl_name,
250 c.col_name,
251 name
252 ));
253 }
254 }
255 _ => {
256 return Err(custom_err!(
258 "missing datatype for {}.{}",
259 tbl_name,
260 c.col_name
261 ));
262 }
263 }
264 }
265 }
266 if options.contains(TableOptions::WITHOUT_ROWID) && !self.has_primary_key() {
267 return Err(custom_err!("PRIMARY KEY missing on table {}", tbl_name,));
268 }
269 }
270 Ok(())
271 }
272
273 pub fn has_primary_key(&self) -> bool {
275 if let Self::ColumnsAndConstraints {
276 columns,
277 constraints,
278 ..
279 } = self
280 {
281 for col in columns.values() {
282 for c in col {
283 if let ColumnConstraint::PrimaryKey { .. } = c {
284 return true;
285 }
286 }
287 }
288 if let Some(constraints) = constraints {
289 for c in constraints {
290 if let TableConstraint::PrimaryKey { .. } = c.constraint {
291 return true;
292 }
293 }
294 }
295 }
296 false
297 }
298}
299
300impl<'a> IntoIterator for &'a ColumnDefinition {
301 type Item = &'a ColumnConstraint;
302 type IntoIter = std::iter::Map<
303 std::slice::Iter<'a, NamedColumnConstraint>,
304 fn(&'a NamedColumnConstraint) -> &'a ColumnConstraint,
305 >;
306
307 fn into_iter(self) -> Self::IntoIter {
308 self.constraints.iter().map(|nc| &nc.constraint)
309 }
310}
311
312impl Select {
313 pub fn column_count(&self) -> ColumnCount {
315 self.body.select.column_count()
316 }
317}
318
319impl OneSelect {
320 pub fn column_count(&self) -> ColumnCount {
322 match self {
323 Self::Select(select) => {
324 let SelectInner { columns, .. } = &**select;
325 column_count(columns)
326 }
327 Self::Values(values) => {
328 assert!(!values.is_empty()); ColumnCount::Fixed(values[0].len())
330 }
331 }
332 }
333 pub fn push(values: &mut Vec<Vec<Expr>>, v: Vec<Expr>) -> Result<(), ParserError> {
335 if values[0].len() != v.len() {
336 return Err(custom_err!("all VALUES must have the same number of terms"));
337 }
338 values.push(v);
339 Ok(())
340 }
341}
342
343impl Display for QualifiedName {
344 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
345 self.to_fmt(f)
346 }
347}
348
349impl ResultColumn {
350 fn column_count(&self) -> ColumnCount {
351 match self {
352 Self::Expr(..) => ColumnCount::Fixed(1),
353 _ => ColumnCount::Dynamic,
354 }
355 }
356}
357fn column_count(cols: &[ResultColumn]) -> ColumnCount {
358 assert!(!cols.is_empty());
359 let mut count = ColumnCount::Fixed(0);
360 for col in cols {
361 match col.column_count() {
362 ColumnCount::Fixed(_) => count.incr(),
363 _ => return ColumnCount::Dynamic,
364 }
365 }
366 count
367}