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 {
60 returning: Some(returning),
61 ..
62 } => column_count(returning),
63 Self::Insert {
64 returning: Some(returning),
65 ..
66 } => column_count(returning),
67 Self::Pragma(..) => ColumnCount::Dynamic,
68 Self::Select(s) => s.column_count(),
69 Self::Update {
70 returning: Some(returning),
71 ..
72 } => column_count(returning),
73 _ => ColumnCount::None,
74 }
75 }
76
77 pub fn readonly(&self) -> bool {
79 match self {
80 Self::Attach { .. } => true,
81 Self::Begin(..) => true,
82 Self::Commit(..) => true,
83 Self::Detach(..) => true,
84 Self::Pragma(..) => true, Self::Reindex { .. } => true,
86 Self::Release(..) => true,
87 Self::Rollback { .. } => true,
88 Self::Savepoint(..) => true,
89 Self::Select(..) => true,
90 _ => false,
91 }
92 }
93
94 pub fn check(&self) -> Result<(), ParserError> {
96 match self {
97 Self::AlterTable(old_name, AlterTableBody::RenameTo(new_name)) => {
98 if *new_name == old_name.name {
99 return Err(custom_err!(
100 "there is already another table or index with this name: {}",
101 new_name
102 ));
103 }
104 Ok(())
105 }
106 Self::AlterTable(.., AlterTableBody::AddColumn(cd)) => {
107 for c in cd {
108 if let ColumnConstraint::PrimaryKey { .. } = c {
109 return Err(custom_err!("Cannot add a PRIMARY KEY column"));
110 } else if let ColumnConstraint::Unique(..) = c {
111 return Err(custom_err!("Cannot add a UNIQUE column"));
112 }
113 }
114 Ok(())
115 }
116 Self::CreateTable {
117 temporary,
118 tbl_name,
119 body,
120 ..
121 } => {
122 if *temporary {
123 if let Some(ref db_name) = tbl_name.db_name {
124 if db_name != "TEMP" {
125 return Err(custom_err!("temporary table name must be unqualified"));
126 }
127 }
128 }
129 body.check(tbl_name)
130 }
131 Self::CreateView {
132 view_name,
133 columns: Some(columns),
134 select,
135 ..
136 } => {
137 for (i, c) in columns.iter().enumerate() {
139 for o in &columns[i + 1..] {
140 if c.col_name == o.col_name {
141 return Err(custom_err!("duplicate column name: {}", c.col_name,));
142 }
143 }
144 }
145 match select.column_count() {
147 ColumnCount::Fixed(n) if n != columns.len() => Err(custom_err!(
148 "expected {} columns for {} but got {}",
149 columns.len(),
150 view_name,
151 n
152 )),
153 _ => Ok(()),
154 }
155 }
156 Self::Delete {
157 order_by: Some(_),
158 limit: None,
159 ..
160 } => Err(custom_err!("ORDER BY without LIMIT on DELETE")),
161 Self::Insert {
162 columns: Some(columns),
163 body: InsertBody::Select(select, ..),
164 ..
165 } => match select.body.select.column_count() {
166 ColumnCount::Fixed(n) if n != columns.len() => {
167 Err(custom_err!("{} values for {} columns", n, columns.len()))
168 }
169 _ => Ok(()),
170 },
171 Self::Insert {
172 columns: Some(columns),
173 body: InsertBody::DefaultValues,
174 ..
175 } => Err(custom_err!("0 values for {} columns", columns.len())),
176 Self::Update {
177 order_by: Some(_),
178 limit: None,
179 ..
180 } => Err(custom_err!("ORDER BY without LIMIT on UPDATE")),
181 _ => Ok(()),
182 }
183 }
184}
185
186impl CreateTableBody {
187 pub fn check(&self, tbl_name: &QualifiedName) -> Result<(), ParserError> {
189 if let Self::ColumnsAndConstraints {
190 columns,
191 constraints: _,
192 options,
193 } = self
194 {
195 let mut generated_count = 0;
196 for c in columns.values() {
197 for cs in &c.constraints {
198 if let ColumnConstraint::Generated { .. } = cs.constraint {
199 generated_count += 1;
200 }
201 }
202 }
203 if generated_count == columns.len() {
204 return Err(custom_err!("must have at least one non-generated column"));
205 }
206
207 if options.contains(TableOptions::STRICT) {
208 for c in columns.values() {
209 match &c.col_type {
210 Some(Type { name, .. }) => {
211 if !(name.eq_ignore_ascii_case("INT")
213 || name.eq_ignore_ascii_case("INTEGER")
214 || name.eq_ignore_ascii_case("REAL")
215 || name.eq_ignore_ascii_case("TEXT")
216 || name.eq_ignore_ascii_case("BLOB")
217 || name.eq_ignore_ascii_case("ANY"))
218 {
219 return Err(custom_err!(
220 "unknown datatype for {}.{}: \"{}\"",
221 tbl_name,
222 c.col_name,
223 name
224 ));
225 }
226 }
227 _ => {
228 return Err(custom_err!(
230 "missing datatype for {}.{}",
231 tbl_name,
232 c.col_name
233 ));
234 }
235 }
236 }
237 }
238 if options.contains(TableOptions::WITHOUT_ROWID) && !self.has_primary_key() {
239 return Err(custom_err!("PRIMARY KEY missing on table {}", tbl_name,));
240 }
241 }
242 Ok(())
243 }
244
245 pub fn has_primary_key(&self) -> bool {
247 if let Self::ColumnsAndConstraints {
248 columns,
249 constraints,
250 ..
251 } = self
252 {
253 for col in columns.values() {
254 for c in col {
255 if let ColumnConstraint::PrimaryKey { .. } = c {
256 return true;
257 }
258 }
259 }
260 if let Some(constraints) = constraints {
261 for c in constraints {
262 if let TableConstraint::PrimaryKey { .. } = c.constraint {
263 return true;
264 }
265 }
266 }
267 }
268 false
269 }
270}
271
272impl<'a> IntoIterator for &'a ColumnDefinition {
273 type Item = &'a ColumnConstraint;
274 type IntoIter = std::iter::Map<
275 std::slice::Iter<'a, NamedColumnConstraint>,
276 fn(&'a NamedColumnConstraint) -> &'a ColumnConstraint,
277 >;
278
279 fn into_iter(self) -> Self::IntoIter {
280 self.constraints.iter().map(|nc| &nc.constraint)
281 }
282}
283
284impl Select {
285 pub fn column_count(&self) -> ColumnCount {
287 self.body.select.column_count()
288 }
289}
290
291impl OneSelect {
292 pub fn column_count(&self) -> ColumnCount {
294 match self {
295 Self::Select { columns, .. } => column_count(columns),
296 Self::Values(values) => {
297 assert!(!values.is_empty()); ColumnCount::Fixed(values[0].len())
299 }
300 }
301 }
302 pub fn push(values: &mut Vec<Vec<Expr>>, v: Vec<Expr>) -> Result<(), ParserError> {
304 if values[0].len() != v.len() {
305 return Err(custom_err!("all VALUES must have the same number of terms"));
306 }
307 values.push(v);
308 Ok(())
309 }
310}
311
312impl Display for QualifiedName {
313 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
314 self.to_fmt(f)
315 }
316}
317
318impl ResultColumn {
319 fn column_count(&self) -> ColumnCount {
320 match self {
321 Self::Expr(..) => ColumnCount::Fixed(1),
322 _ => ColumnCount::Dynamic,
323 }
324 }
325}
326fn column_count(cols: &[ResultColumn]) -> ColumnCount {
327 assert!(!cols.is_empty());
328 let mut count = ColumnCount::Fixed(0);
329 for col in cols {
330 match col.column_count() {
331 ColumnCount::Fixed(_) => count.incr(),
332 _ => return ColumnCount::Dynamic,
333 }
334 }
335 count
336}