sqlint/ast/
query.rs

1use crate::ast::{Delete, Insert, Merge, Select, Union, Update};
2use std::borrow::Cow;
3
4use super::IntoCommonTableExpression;
5
6/// A database query
7#[derive(Debug, Clone, PartialEq)]
8pub enum Query<'a> {
9    Select(Box<Select<'a>>),
10    Insert(Box<Insert<'a>>),
11    Update(Box<Update<'a>>),
12    Delete(Box<Delete<'a>>),
13    Union(Box<Union<'a>>),
14    Merge(Box<Merge<'a>>),
15    Raw(Cow<'a, str>),
16}
17
18impl<'a, T> From<T> for Query<'a>
19where
20    T: Into<Cow<'a, str>>,
21{
22    fn from(t: T) -> Self {
23        Query::Raw(t.into())
24    }
25}
26
27impl<'a> Query<'a> {
28    pub fn is_select(&self) -> bool {
29        matches!(self, Query::Select(_))
30    }
31
32    pub fn is_insert(&self) -> bool {
33        matches!(self, Query::Insert(_))
34    }
35
36    pub fn is_update(&self) -> bool {
37        matches!(self, Query::Update(_))
38    }
39
40    pub fn is_delete(&self) -> bool {
41        matches!(self, Query::Delete(_))
42    }
43
44    pub fn is_union(&self) -> bool {
45        matches!(self, Query::Union(_))
46    }
47}
48
49/// A database query that only returns data without modifying anything.
50#[derive(Debug, Clone, PartialEq)]
51pub enum SelectQuery<'a> {
52    Select(Box<Select<'a>>),
53    Union(Box<Union<'a>>),
54}
55
56impl<'a> SelectQuery<'a> {
57    /// Finds all named values or columns from the selection.
58    pub fn named_selection(&self) -> Vec<String> {
59        match self {
60            Self::Select(s) => s.named_selection(),
61            Self::Union(u) => u.named_selection(),
62        }
63    }
64
65    #[cfg(feature = "mssql")]
66    pub(crate) fn convert_tuple_selects_to_ctes(
67        self,
68        level: &mut usize,
69    ) -> (Self, Vec<super::CommonTableExpression<'a>>) {
70        match self {
71            Self::Select(select) => match select.convert_tuple_selects_to_ctes(false, level) {
72                either::Either::Left(select) => (Self::Select(Box::new(select)), Vec::new()),
73                either::Either::Right((select, ctes)) => {
74                    let select = Self::Select(Box::new(select));
75                    (select, ctes)
76                }
77            },
78            Self::Union(union) => match union.convert_tuple_selects_into_ctes(false, level) {
79                either::Either::Left(union) => (Self::Union(Box::new(union)), Vec::new()),
80                either::Either::Right((union, ctes)) => {
81                    let union = Self::Union(Box::new(union));
82                    (union, ctes)
83                }
84            },
85        }
86    }
87}
88
89impl<'a> From<Select<'a>> for SelectQuery<'a> {
90    fn from(s: Select<'a>) -> Self {
91        Self::Select(Box::new(s))
92    }
93}
94
95impl<'a> From<Union<'a>> for SelectQuery<'a> {
96    fn from(u: Union<'a>) -> Self {
97        Self::Union(Box::new(u))
98    }
99}
100
101impl<'a> From<SelectQuery<'a>> for Query<'a> {
102    fn from(sq: SelectQuery<'a>) -> Self {
103        match sq {
104            SelectQuery::Select(s) => Query::Select(s),
105            SelectQuery::Union(u) => Query::Union(u),
106        }
107    }
108}
109
110impl<'a> IntoCommonTableExpression<'a> for SelectQuery<'a> {}