1pub mod check;
4pub mod fmt;
5
6use std::num::ParseIntError;
7use std::ops::Deref;
8use std::str::{self, Bytes, FromStr};
9
10use fmt::{ToTokens, TokenStream};
11use indexmap::{IndexMap, IndexSet};
12
13use crate::custom_err;
14use crate::dialect::TokenType::{self, *};
15use crate::dialect::{from_token, is_identifier, Token};
16use crate::parser::{parse::YYCODETYPE, ParserError};
17
18#[derive(Default)]
20pub struct ParameterInfo {
21 pub count: u32,
23 pub names: IndexSet<String>,
25}
26
27impl TokenStream for ParameterInfo {
29 type Error = ParseIntError;
30
31 fn append(&mut self, ty: TokenType, value: Option<&str>) -> Result<(), Self::Error> {
32 if ty == TK_VARIABLE {
33 if let Some(variable) = value {
34 if variable == "?" {
35 self.count = self.count.saturating_add(1);
36 } else if variable.as_bytes()[0] == b'?' {
37 let n = u32::from_str(&variable[1..])?;
38 if n > self.count {
39 self.count = n;
40 }
41 } else if self.names.insert(variable.to_owned()) {
42 self.count = self.count.saturating_add(1);
43 }
44 }
45 }
46 Ok(())
47 }
48}
49
50#[derive(Clone, Debug, PartialEq, Eq)]
53pub enum Cmd {
54 Explain(Stmt),
56 ExplainQueryPlan(Stmt),
58 Stmt(Stmt),
60}
61
62pub(crate) enum ExplainKind {
63 Explain,
64 QueryPlan,
65}
66
67#[derive(Clone, Debug, PartialEq, Eq)]
70pub enum Stmt {
71 AlterTable(QualifiedName, AlterTableBody),
73 Analyze(Option<QualifiedName>),
75 Attach {
77 expr: Expr,
80 db_name: Expr,
82 key: Option<Expr>,
84 },
85 Begin(Option<TransactionType>, Option<Name>),
87 Commit(Option<Name>), CreateIndex {
91 unique: bool,
93 if_not_exists: bool,
95 idx_name: QualifiedName,
97 tbl_name: Name,
99 columns: Vec<SortedColumn>,
101 where_clause: Option<Expr>,
103 },
104 CreateTable {
106 temporary: bool, if_not_exists: bool,
110 tbl_name: QualifiedName,
112 body: CreateTableBody,
114 },
115 CreateTrigger {
117 temporary: bool,
119 if_not_exists: bool,
121 trigger_name: QualifiedName,
123 time: Option<TriggerTime>,
125 event: TriggerEvent,
127 tbl_name: QualifiedName,
129 for_each_row: bool,
131 when_clause: Option<Expr>,
133 commands: Vec<TriggerCmd>,
135 },
136 CreateView {
138 temporary: bool,
140 if_not_exists: bool,
142 view_name: QualifiedName,
144 columns: Option<Vec<IndexedColumn>>,
146 select: Box<Select>,
148 },
149 CreateVirtualTable {
151 if_not_exists: bool,
153 tbl_name: QualifiedName,
155 module_name: Name,
157 args: Option<Vec<String>>, },
160 Delete {
162 with: Option<With>,
164 tbl_name: QualifiedName,
166 indexed: Option<Indexed>,
168 where_clause: Option<Expr>,
170 returning: Option<Vec<ResultColumn>>,
172 order_by: Option<Vec<SortedColumn>>,
174 limit: Option<Limit>,
176 },
177 Detach(Expr), DropIndex {
181 if_exists: bool,
183 idx_name: QualifiedName,
185 },
186 DropTable {
188 if_exists: bool,
190 tbl_name: QualifiedName,
192 },
193 DropTrigger {
195 if_exists: bool,
197 trigger_name: QualifiedName,
199 },
200 DropView {
202 if_exists: bool,
204 view_name: QualifiedName,
206 },
207 Insert {
209 with: Option<With>,
211 or_conflict: Option<ResolveType>, tbl_name: QualifiedName,
215 columns: Option<DistinctNames>,
217 body: InsertBody,
219 returning: Option<Vec<ResultColumn>>,
221 },
222 Pragma(QualifiedName, Option<PragmaBody>),
224 Reindex {
226 obj_name: Option<QualifiedName>,
228 },
229 Release(Name), Rollback {
233 tx_name: Option<Name>,
235 savepoint_name: Option<Name>, },
238 Savepoint(Name),
240 Select(Box<Select>),
242 Update {
244 with: Option<With>,
246 or_conflict: Option<ResolveType>,
248 tbl_name: QualifiedName,
250 indexed: Option<Indexed>,
252 sets: Vec<Set>,
254 from: Option<FromClause>,
256 where_clause: Option<Expr>,
258 returning: Option<Vec<ResultColumn>>,
260 order_by: Option<Vec<SortedColumn>>,
262 limit: Option<Limit>,
264 },
265 Vacuum(Option<Name>, Option<Expr>),
267}
268
269#[derive(Clone, Debug, PartialEq, Eq)]
272pub enum Expr {
273 Between {
275 lhs: Box<Expr>,
277 not: bool,
279 start: Box<Expr>,
281 end: Box<Expr>,
283 },
284 Binary(Box<Expr>, Operator, Box<Expr>),
286 Case {
288 base: Option<Box<Expr>>,
290 when_then_pairs: Vec<(Expr, Expr)>,
292 else_expr: Option<Box<Expr>>,
294 },
295 Cast {
297 expr: Box<Expr>,
299 type_name: Option<Type>,
301 },
302 Collate(Box<Expr>, String),
304 DoublyQualified(Name, Name, Name),
306 Exists(Box<Select>),
308 FunctionCall {
310 name: Id,
312 distinctness: Option<Distinctness>,
314 args: Option<Vec<Expr>>,
316 order_by: Option<Vec<SortedColumn>>,
318 filter_over: Option<FunctionTail>,
320 },
321 FunctionCallStar {
323 name: Id,
325 filter_over: Option<FunctionTail>,
327 },
328 Id(Id),
330 InList {
332 lhs: Box<Expr>,
334 not: bool,
336 rhs: Option<Vec<Expr>>,
338 },
339 InSelect {
341 lhs: Box<Expr>,
343 not: bool,
345 rhs: Box<Select>,
347 },
348 InTable {
350 lhs: Box<Expr>,
352 not: bool,
354 rhs: QualifiedName,
356 args: Option<Vec<Expr>>,
358 },
359 IsNull(Box<Expr>),
361 Like {
363 lhs: Box<Expr>,
365 not: bool,
367 op: LikeOperator,
369 rhs: Box<Expr>,
371 escape: Option<Box<Expr>>,
373 },
374 Literal(Literal),
376 Name(Name),
378 NotNull(Box<Expr>),
380 Parenthesized(Vec<Expr>),
382 Qualified(Name, Name),
384 Raise(ResolveType, Option<Box<Expr>>),
386 Subquery(Box<Select>),
388 Unary(UnaryOperator, Box<Expr>),
390 Variable(String),
392}
393
394impl Expr {
395 pub fn parenthesized(x: Self) -> Self {
397 Self::Parenthesized(vec![x])
398 }
399 pub fn id(xt: YYCODETYPE, x: Token) -> Self {
401 Self::Id(Id::from_token(xt, x))
402 }
403 pub fn collate(x: Self, ct: YYCODETYPE, c: Token) -> Self {
405 Self::Collate(Box::new(x), from_token(ct, c))
406 }
407 pub fn cast(x: Self, type_name: Option<Type>) -> Self {
409 Self::Cast {
410 expr: Box::new(x),
411 type_name,
412 }
413 }
414 pub fn binary(left: Self, op: YYCODETYPE, right: Self) -> Self {
416 Self::Binary(Box::new(left), Operator::from(op), Box::new(right))
417 }
418 pub fn ptr(left: Self, op: Token, right: Self) -> Self {
420 let mut ptr = Operator::ArrowRight;
421 if op.1 == b"->>" {
422 ptr = Operator::ArrowRightShift;
423 }
424 Self::Binary(Box::new(left), ptr, Box::new(right))
425 }
426 pub fn like(lhs: Self, not: bool, op: LikeOperator, rhs: Self, escape: Option<Self>) -> Self {
428 Self::Like {
429 lhs: Box::new(lhs),
430 not,
431 op,
432 rhs: Box::new(rhs),
433 escape: escape.map(Box::new),
434 }
435 }
436 pub fn not_null(x: Self, op: YYCODETYPE) -> Self {
438 if op == TK_ISNULL as YYCODETYPE {
439 Self::IsNull(Box::new(x))
440 } else if op == TK_NOTNULL as YYCODETYPE {
441 Self::NotNull(Box::new(x))
442 } else {
443 unreachable!()
444 }
445 }
446 pub fn unary(op: UnaryOperator, x: Self) -> Self {
448 Self::Unary(op, Box::new(x))
449 }
450 pub fn between(lhs: Self, not: bool, start: Self, end: Self) -> Self {
452 Self::Between {
453 lhs: Box::new(lhs),
454 not,
455 start: Box::new(start),
456 end: Box::new(end),
457 }
458 }
459 pub fn in_list(lhs: Self, not: bool, rhs: Option<Vec<Self>>) -> Self {
461 Self::InList {
462 lhs: Box::new(lhs),
463 not,
464 rhs,
465 }
466 }
467 pub fn in_select(lhs: Self, not: bool, rhs: Select) -> Self {
469 Self::InSelect {
470 lhs: Box::new(lhs),
471 not,
472 rhs: Box::new(rhs),
473 }
474 }
475 pub fn in_table(lhs: Self, not: bool, rhs: QualifiedName, args: Option<Vec<Self>>) -> Self {
477 Self::InTable {
478 lhs: Box::new(lhs),
479 not,
480 rhs,
481 args,
482 }
483 }
484 pub fn sub_query(query: Select) -> Self {
486 Self::Subquery(Box::new(query))
487 }
488}
489
490#[derive(Clone, Debug, PartialEq, Eq)]
492pub enum Literal {
493 Numeric(String),
495 String(String),
498 Blob(String),
501 Keyword(String),
503 Null,
505 CurrentDate,
507 CurrentTime,
509 CurrentTimestamp,
511}
512
513impl Literal {
514 pub fn from_ctime_kw(token: Token) -> Self {
516 if b"CURRENT_DATE".eq_ignore_ascii_case(token.1) {
517 Self::CurrentDate
518 } else if b"CURRENT_TIME".eq_ignore_ascii_case(token.1) {
519 Self::CurrentTime
520 } else if b"CURRENT_TIMESTAMP".eq_ignore_ascii_case(token.1) {
521 Self::CurrentTimestamp
522 } else {
523 unreachable!()
524 }
525 }
526}
527
528#[derive(Copy, Clone, Debug, PartialEq, Eq)]
530pub enum LikeOperator {
531 Glob,
533 Like,
535 Match,
537 Regexp,
539}
540
541impl LikeOperator {
542 pub fn from_token(token_type: YYCODETYPE, token: Token) -> Self {
544 if token_type == TK_MATCH as YYCODETYPE {
545 return Self::Match;
546 } else if token_type == TK_LIKE_KW as YYCODETYPE {
547 let token = token.1;
548 if b"LIKE".eq_ignore_ascii_case(token) {
549 return Self::Like;
550 } else if b"GLOB".eq_ignore_ascii_case(token) {
551 return Self::Glob;
552 } else if b"REGEXP".eq_ignore_ascii_case(token) {
553 return Self::Regexp;
554 }
555 }
556 unreachable!()
557 }
558}
559
560#[derive(Copy, Clone, Debug, PartialEq, Eq)]
562pub enum Operator {
563 Add,
565 And,
567 ArrowRight,
569 ArrowRightShift,
571 BitwiseAnd,
573 BitwiseOr,
575 Concat,
577 Equals,
579 Divide,
581 Greater,
583 GreaterEquals,
585 Is,
587 IsNot,
589 LeftShift,
591 Less,
593 LessEquals,
595 Modulus,
597 Multiply,
599 NotEquals,
601 Or,
603 RightShift,
605 Subtract,
607}
608
609impl From<YYCODETYPE> for Operator {
610 fn from(token_type: YYCODETYPE) -> Self {
611 match token_type {
612 x if x == TK_AND as YYCODETYPE => Self::And,
613 x if x == TK_OR as YYCODETYPE => Self::Or,
614 x if x == TK_LT as YYCODETYPE => Self::Less,
615 x if x == TK_GT as YYCODETYPE => Self::Greater,
616 x if x == TK_GE as YYCODETYPE => Self::GreaterEquals,
617 x if x == TK_LE as YYCODETYPE => Self::LessEquals,
618 x if x == TK_EQ as YYCODETYPE => Self::Equals,
619 x if x == TK_NE as YYCODETYPE => Self::NotEquals,
620 x if x == TK_BITAND as YYCODETYPE => Self::BitwiseAnd,
621 x if x == TK_BITOR as YYCODETYPE => Self::BitwiseOr,
622 x if x == TK_LSHIFT as YYCODETYPE => Self::LeftShift,
623 x if x == TK_RSHIFT as YYCODETYPE => Self::RightShift,
624 x if x == TK_PLUS as YYCODETYPE => Self::Add,
625 x if x == TK_MINUS as YYCODETYPE => Self::Subtract,
626 x if x == TK_STAR as YYCODETYPE => Self::Multiply,
627 x if x == TK_SLASH as YYCODETYPE => Self::Divide,
628 x if x == TK_REM as YYCODETYPE => Self::Modulus,
629 x if x == TK_CONCAT as YYCODETYPE => Self::Concat,
630 x if x == TK_IS as YYCODETYPE => Self::Is,
631 x if x == TK_NOT as YYCODETYPE => Self::IsNot,
632 _ => unreachable!(),
633 }
634 }
635}
636
637#[derive(Copy, Clone, Debug, PartialEq, Eq)]
639pub enum UnaryOperator {
640 BitwiseNot,
642 Negative,
644 Not,
646 Positive,
648}
649
650impl From<YYCODETYPE> for UnaryOperator {
651 fn from(token_type: YYCODETYPE) -> Self {
652 match token_type {
653 x if x == TK_BITNOT as YYCODETYPE => Self::BitwiseNot,
654 x if x == TK_MINUS as YYCODETYPE => Self::Negative,
655 x if x == TK_NOT as YYCODETYPE => Self::Not,
656 x if x == TK_PLUS as YYCODETYPE => Self::Positive,
657 _ => unreachable!(),
658 }
659 }
660}
661
662#[derive(Clone, Debug, PartialEq, Eq)]
666pub struct Select {
667 pub with: Option<With>,
669 pub body: SelectBody,
671 pub order_by: Option<Vec<SortedColumn>>, pub limit: Option<Limit>,
675}
676
677#[derive(Clone, Debug, PartialEq, Eq)]
679pub struct SelectBody {
680 pub select: OneSelect,
682 pub compounds: Option<Vec<CompoundSelect>>,
684}
685
686impl SelectBody {
687 pub(crate) fn push(&mut self, cs: CompoundSelect) -> Result<(), ParserError> {
688 use crate::ast::check::ColumnCount;
689 if let ColumnCount::Fixed(n) = self.select.column_count() {
690 if let ColumnCount::Fixed(m) = cs.select.column_count() {
691 if n != m {
692 return Err(custom_err!(
693 "SELECTs to the left and right of {} do not have the same number of result columns",
694 cs.operator
695 ));
696 }
697 }
698 }
699 if let Some(ref mut v) = self.compounds {
700 v.push(cs);
701 } else {
702 self.compounds = Some(vec![cs]);
703 }
704 Ok(())
705 }
706}
707
708#[derive(Clone, Debug, PartialEq, Eq)]
710pub struct CompoundSelect {
711 pub operator: CompoundOperator,
713 pub select: OneSelect,
715}
716
717#[derive(Copy, Clone, Debug, PartialEq, Eq)]
720pub enum CompoundOperator {
721 Union,
723 UnionAll,
725 Except,
727 Intersect,
729}
730
731#[derive(Clone, Debug, PartialEq, Eq)]
734pub enum OneSelect {
735 Select {
737 distinctness: Option<Distinctness>,
739 columns: Vec<ResultColumn>,
741 from: Option<FromClause>,
743 where_clause: Option<Expr>,
745 group_by: Option<GroupBy>,
747 window_clause: Option<Vec<WindowDef>>,
749 },
750 Values(Vec<Vec<Expr>>),
752}
753
754#[derive(Clone, Debug, PartialEq, Eq)]
757pub struct FromClause {
758 pub select: Option<Box<SelectTable>>, pub joins: Option<Vec<JoinedSelectTable>>,
762 op: Option<JoinOperator>, }
764impl FromClause {
765 pub(crate) fn empty() -> Self {
766 Self {
767 select: None,
768 joins: None,
769 op: None,
770 }
771 }
772
773 pub(crate) fn push(
774 &mut self,
775 table: SelectTable,
776 jc: Option<JoinConstraint>,
777 ) -> Result<(), ParserError> {
778 let op = self.op.take();
779 if let Some(op) = op {
780 let jst = JoinedSelectTable {
781 operator: op,
782 table,
783 constraint: jc,
784 };
785 if jst.operator.is_natural() && jst.constraint.is_some() {
786 return Err(custom_err!(
787 "a NATURAL join may not have an ON or USING clause"
788 ));
789 }
790 if let Some(ref mut joins) = self.joins {
791 joins.push(jst);
792 } else {
793 self.joins = Some(vec![jst]);
794 }
795 } else {
796 if jc.is_some() {
797 return Err(custom_err!("a JOIN clause is required before ON"));
798 }
799 debug_assert!(self.select.is_none());
800 debug_assert!(self.joins.is_none());
801 self.select = Some(Box::new(table));
802 }
803 Ok(())
804 }
805
806 pub(crate) fn push_op(&mut self, op: JoinOperator) {
807 self.op = Some(op);
808 }
809}
810
811#[derive(Copy, Clone, Debug, PartialEq, Eq)]
813pub enum Distinctness {
814 Distinct,
816 All,
818}
819
820#[derive(Clone, Debug, PartialEq, Eq)]
823pub enum ResultColumn {
824 Expr(Expr, Option<As>),
826 Star,
828 TableStar(Name),
830}
831
832#[derive(Clone, Debug, PartialEq, Eq)]
834pub enum As {
835 As(Name),
837 Elided(Name), }
840
841#[derive(Clone, Debug, PartialEq, Eq)]
844pub struct JoinedSelectTable {
845 pub operator: JoinOperator,
847 pub table: SelectTable,
849 pub constraint: Option<JoinConstraint>,
851}
852
853#[derive(Clone, Debug, PartialEq, Eq)]
856pub enum SelectTable {
857 Table(QualifiedName, Option<As>, Option<Indexed>),
859 TableCall(QualifiedName, Option<Vec<Expr>>, Option<As>),
861 Select(Box<Select>, Option<As>),
863 Sub(FromClause, Option<As>),
865}
866
867#[derive(Copy, Clone, Debug, PartialEq, Eq)]
870pub enum JoinOperator {
871 Comma,
873 TypedJoin(Option<JoinType>),
875}
876
877impl JoinOperator {
878 pub(crate) fn from(
879 token: Token,
880 n1: Option<Name>,
881 n2: Option<Name>,
882 ) -> Result<Self, ParserError> {
883 Ok({
884 let mut jt = JoinType::try_from(token.1)?;
885 for n in [&n1, &n2].into_iter().flatten() {
886 jt |= JoinType::try_from(n.0.as_ref())?;
887 }
888 if (jt & (JoinType::INNER | JoinType::OUTER)) == (JoinType::INNER | JoinType::OUTER)
889 || (jt & (JoinType::OUTER | JoinType::LEFT | JoinType::RIGHT)) == JoinType::OUTER
890 {
891 return Err(custom_err!(
892 "unsupported JOIN type: {:?} {:?} {:?}",
893 str::from_utf8(token.1),
894 n1,
895 n2
896 ));
897 }
898 Self::TypedJoin(Some(jt))
899 })
900 }
901 fn is_natural(&self) -> bool {
902 match self {
903 Self::TypedJoin(Some(jt)) => jt.contains(JoinType::NATURAL),
904 _ => false,
905 }
906 }
907}
908
909bitflags::bitflags! {
911 #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
913 pub struct JoinType: u8 {
914 const INNER = 0x01;
916 const CROSS = 0x02;
918 const NATURAL = 0x04;
920 const LEFT = 0x08;
922 const RIGHT = 0x10;
924 const OUTER = 0x20;
926 }
927}
928
929impl TryFrom<&[u8]> for JoinType {
930 type Error = ParserError;
931 fn try_from(s: &[u8]) -> Result<Self, ParserError> {
932 if b"CROSS".eq_ignore_ascii_case(s) {
933 Ok(Self::INNER | Self::CROSS)
934 } else if b"FULL".eq_ignore_ascii_case(s) {
935 Ok(Self::LEFT | Self::RIGHT | Self::OUTER)
936 } else if b"INNER".eq_ignore_ascii_case(s) {
937 Ok(Self::INNER)
938 } else if b"LEFT".eq_ignore_ascii_case(s) {
939 Ok(Self::LEFT | Self::OUTER)
940 } else if b"NATURAL".eq_ignore_ascii_case(s) {
941 Ok(Self::NATURAL)
942 } else if b"RIGHT".eq_ignore_ascii_case(s) {
943 Ok(Self::RIGHT | Self::OUTER)
944 } else if b"OUTER".eq_ignore_ascii_case(s) {
945 Ok(Self::OUTER)
946 } else {
947 Err(custom_err!(
948 "unsupported JOIN type: {:?}",
949 str::from_utf8(s)
950 ))
951 }
952 }
953}
954
955#[derive(Clone, Debug, PartialEq, Eq)]
957pub enum JoinConstraint {
958 On(Expr),
960 Using(DistinctNames),
962}
963
964#[derive(Clone, Debug, PartialEq, Eq)]
966pub struct GroupBy {
967 pub exprs: Vec<Expr>,
969 pub having: Option<Expr>, }
972
973#[derive(Clone, Debug, PartialEq, Eq)]
975pub struct Id(pub String);
976
977impl Id {
978 pub fn from_token(ty: YYCODETYPE, token: Token) -> Self {
980 Self(from_token(ty, token))
981 }
982}
983
984#[derive(Clone, Debug, Eq)]
988pub struct Name(pub String); impl Name {
991 pub fn from_token(ty: YYCODETYPE, token: Token) -> Self {
993 Self(from_token(ty, token))
994 }
995
996 fn as_bytes(&self) -> QuotedIterator<'_> {
997 if self.0.is_empty() {
998 return QuotedIterator(self.0.bytes(), 0);
999 }
1000 let bytes = self.0.as_bytes();
1001 let mut quote = bytes[0];
1002 if quote != b'"' && quote != b'`' && quote != b'\'' && quote != b'[' {
1003 return QuotedIterator(self.0.bytes(), 0);
1004 } else if quote == b'[' {
1005 quote = b']';
1006 }
1007 debug_assert!(bytes.len() > 1);
1008 debug_assert_eq!(quote, bytes[bytes.len() - 1]);
1009 let sub = &self.0.as_str()[1..bytes.len() - 1];
1010 if quote == b']' {
1011 return QuotedIterator(sub.bytes(), 0); }
1013 QuotedIterator(sub.bytes(), quote)
1014 }
1015}
1016
1017struct QuotedIterator<'s>(Bytes<'s>, u8);
1018impl Iterator for QuotedIterator<'_> {
1019 type Item = u8;
1020
1021 fn next(&mut self) -> Option<u8> {
1022 match self.0.next() {
1023 x @ Some(b) => {
1024 if b == self.1 && self.0.next() != Some(self.1) {
1025 panic!("Malformed string literal: {:?}", self.0);
1026 }
1027 x
1028 }
1029 x => x,
1030 }
1031 }
1032
1033 fn size_hint(&self) -> (usize, Option<usize>) {
1034 if self.1 == 0 {
1035 return self.0.size_hint();
1036 }
1037 (0, None)
1038 }
1039}
1040
1041fn eq_ignore_case_and_quote(mut it: QuotedIterator<'_>, mut other: QuotedIterator<'_>) -> bool {
1042 loop {
1043 match (it.next(), other.next()) {
1044 (Some(b1), Some(b2)) => {
1045 if !b1.eq_ignore_ascii_case(&b2) {
1046 return false;
1047 }
1048 }
1049 (None, None) => break,
1050 _ => return false,
1051 }
1052 }
1053 true
1054}
1055
1056impl std::hash::Hash for Name {
1058 fn hash<H: std::hash::Hasher>(&self, hasher: &mut H) {
1059 self.as_bytes()
1060 .for_each(|b| hasher.write_u8(b.to_ascii_lowercase()));
1061 }
1062}
1063impl PartialEq for Name {
1065 fn eq(&self, other: &Self) -> bool {
1066 eq_ignore_case_and_quote(self.as_bytes(), other.as_bytes())
1067 }
1068}
1069impl PartialEq<str> for Name {
1071 fn eq(&self, other: &str) -> bool {
1072 eq_ignore_case_and_quote(self.as_bytes(), QuotedIterator(other.bytes(), 0u8))
1073 }
1074}
1075impl PartialEq<&str> for Name {
1077 fn eq(&self, other: &&str) -> bool {
1078 eq_ignore_case_and_quote(self.as_bytes(), QuotedIterator(other.bytes(), 0u8))
1079 }
1080}
1081
1082#[derive(Clone, Debug, PartialEq, Eq)]
1084pub struct QualifiedName {
1085 pub db_name: Option<Name>,
1087 pub name: Name,
1089 pub alias: Option<Name>, }
1092
1093impl QualifiedName {
1094 pub fn single(name: Name) -> Self {
1096 Self {
1097 db_name: None,
1098 name,
1099 alias: None,
1100 }
1101 }
1102 pub fn fullname(db_name: Name, name: Name) -> Self {
1104 Self {
1105 db_name: Some(db_name),
1106 name,
1107 alias: None,
1108 }
1109 }
1110 pub fn xfullname(db_name: Name, name: Name, alias: Name) -> Self {
1112 Self {
1113 db_name: Some(db_name),
1114 name,
1115 alias: Some(alias),
1116 }
1117 }
1118 pub fn alias(name: Name, alias: Name) -> Self {
1120 Self {
1121 db_name: None,
1122 name,
1123 alias: Some(alias),
1124 }
1125 }
1126}
1127
1128#[derive(Clone, Debug, PartialEq, Eq)]
1130pub struct DistinctNames(IndexSet<Name>);
1131
1132impl DistinctNames {
1133 pub fn new(name: Name) -> Self {
1135 let mut dn = Self(IndexSet::new());
1136 dn.0.insert(name);
1137 dn
1138 }
1139 pub fn single(name: Name) -> Self {
1141 let mut dn = Self(IndexSet::with_capacity(1));
1142 dn.0.insert(name);
1143 dn
1144 }
1145 pub fn insert(&mut self, name: Name) -> Result<(), ParserError> {
1147 if self.0.contains(&name) {
1148 return Err(custom_err!("column \"{}\" specified more than once", name));
1149 }
1150 self.0.insert(name);
1151 Ok(())
1152 }
1153}
1154impl Deref for DistinctNames {
1155 type Target = IndexSet<Name>;
1156
1157 fn deref(&self) -> &IndexSet<Name> {
1158 &self.0
1159 }
1160}
1161
1162#[derive(Clone, Debug, PartialEq, Eq)]
1165pub enum AlterTableBody {
1166 RenameTo(Name),
1168 AddColumn(ColumnDefinition), RenameColumn {
1172 old: Name,
1174 new: Name,
1176 },
1177 DropColumn(Name), }
1180
1181#[derive(Clone, Debug, PartialEq, Eq)]
1185pub enum CreateTableBody {
1186 ColumnsAndConstraints {
1188 columns: IndexMap<Name, ColumnDefinition>,
1190 constraints: Option<Vec<NamedTableConstraint>>,
1192 options: TableOptions,
1194 },
1195 AsSelect(Box<Select>),
1197}
1198
1199impl CreateTableBody {
1200 pub fn columns_and_constraints(
1202 columns: IndexMap<Name, ColumnDefinition>,
1203 constraints: Option<Vec<NamedTableConstraint>>,
1204 options: TableOptions,
1205 ) -> Result<Self, ParserError> {
1206 Ok(Self::ColumnsAndConstraints {
1207 columns,
1208 constraints,
1209 options,
1210 })
1211 }
1212}
1213
1214#[derive(Clone, Debug, PartialEq, Eq)]
1217pub struct ColumnDefinition {
1218 pub col_name: Name,
1220 pub col_type: Option<Type>,
1222 pub constraints: Vec<NamedColumnConstraint>,
1224}
1225
1226impl ColumnDefinition {
1227 pub fn add_column(columns: &mut IndexMap<Name, Self>, mut cd: Self) -> Result<(), ParserError> {
1229 let col_name = &cd.col_name;
1230 if columns.contains_key(col_name) {
1231 return Err(custom_err!("duplicate column name: {}", col_name));
1233 }
1234 if let Some(ref mut col_type) = cd.col_type {
1236 let mut split = col_type.name.split_ascii_whitespace();
1237 let truncate = if split
1238 .next_back()
1239 .is_some_and(|s| s.eq_ignore_ascii_case("ALWAYS"))
1240 && split
1241 .next_back()
1242 .is_some_and(|s| s.eq_ignore_ascii_case("GENERATED"))
1243 {
1244 let mut generated = false;
1245 for constraint in &cd.constraints {
1246 if let ColumnConstraint::Generated { .. } = constraint.constraint {
1247 generated = true;
1248 break;
1249 }
1250 }
1251 generated
1252 } else {
1253 false
1254 };
1255 if truncate {
1256 let new_type: Vec<&str> = split.collect();
1258 col_type.name = new_type.join(" ");
1259 }
1260 }
1261 for constraint in &cd.constraints {
1262 if let ColumnConstraint::ForeignKey {
1263 clause:
1264 ForeignKeyClause {
1265 tbl_name, columns, ..
1266 },
1267 ..
1268 } = &constraint.constraint
1269 {
1270 if columns.as_ref().map_or(0, Vec::len) > 1 {
1272 return Err(custom_err!(
1273 "foreign key on {} should reference only one column of table {}",
1274 col_name,
1275 tbl_name
1276 ));
1277 }
1278 }
1279 }
1280 columns.insert(col_name.clone(), cd);
1281 Ok(())
1282 }
1283}
1284
1285#[derive(Clone, Debug, PartialEq, Eq)]
1288pub struct NamedColumnConstraint {
1289 pub name: Option<Name>,
1291 pub constraint: ColumnConstraint,
1293}
1294
1295#[derive(Clone, Debug, PartialEq, Eq)]
1298pub enum ColumnConstraint {
1299 PrimaryKey {
1301 order: Option<SortOrder>,
1303 conflict_clause: Option<ResolveType>,
1305 auto_increment: bool,
1307 },
1308 NotNull {
1310 nullable: bool,
1312 conflict_clause: Option<ResolveType>,
1314 },
1315 Unique(Option<ResolveType>),
1317 Check(Expr),
1319 Default(Expr),
1321 Defer(DeferSubclause), Collate {
1325 collation_name: Name, },
1328 ForeignKey {
1330 clause: ForeignKeyClause,
1332 deref_clause: Option<DeferSubclause>,
1334 },
1335 Generated {
1337 expr: Expr,
1339 typ: Option<Id>,
1341 },
1342}
1343
1344#[derive(Clone, Debug, PartialEq, Eq)]
1347pub struct NamedTableConstraint {
1348 pub name: Option<Name>,
1350 pub constraint: TableConstraint,
1352}
1353
1354#[derive(Clone, Debug, PartialEq, Eq)]
1357pub enum TableConstraint {
1358 PrimaryKey {
1360 columns: Vec<SortedColumn>,
1362 auto_increment: bool,
1364 conflict_clause: Option<ResolveType>,
1366 },
1367 Unique {
1369 columns: Vec<SortedColumn>,
1371 conflict_clause: Option<ResolveType>,
1373 },
1374 Check(Expr),
1376 ForeignKey {
1378 columns: Vec<IndexedColumn>,
1380 clause: ForeignKeyClause,
1382 deref_clause: Option<DeferSubclause>,
1384 },
1385}
1386
1387bitflags::bitflags! {
1388 #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1390 pub struct TableOptions: u8 {
1391 const NONE = 0;
1393 const WITHOUT_ROWID = 1;
1395 const STRICT = 2;
1397 }
1398}
1399
1400#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1402pub enum SortOrder {
1403 Asc,
1405 Desc,
1407}
1408
1409#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1411pub enum NullsOrder {
1412 First,
1414 Last,
1416}
1417
1418#[derive(Clone, Debug, PartialEq, Eq)]
1421pub struct ForeignKeyClause {
1422 pub tbl_name: Name,
1424 pub columns: Option<Vec<IndexedColumn>>,
1426 pub args: Vec<RefArg>,
1428}
1429
1430#[derive(Clone, Debug, PartialEq, Eq)]
1432pub enum RefArg {
1433 OnDelete(RefAct),
1435 OnInsert(RefAct),
1437 OnUpdate(RefAct),
1439 Match(Name),
1441}
1442
1443#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1445pub enum RefAct {
1446 SetNull,
1448 SetDefault,
1450 Cascade,
1452 Restrict,
1454 NoAction,
1456}
1457
1458#[derive(Clone, Debug, PartialEq, Eq)]
1460pub struct DeferSubclause {
1461 pub deferrable: bool,
1463 pub init_deferred: Option<InitDeferredPred>,
1465}
1466
1467#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1469pub enum InitDeferredPred {
1470 InitiallyDeferred,
1472 InitiallyImmediate, }
1475
1476#[derive(Clone, Debug, PartialEq, Eq)]
1479pub struct IndexedColumn {
1480 pub col_name: Name,
1482 pub collation_name: Option<Name>, pub order: Option<SortOrder>,
1486}
1487
1488#[derive(Clone, Debug, PartialEq, Eq)]
1490pub enum Indexed {
1491 IndexedBy(Name),
1493 NotIndexed,
1495}
1496
1497#[derive(Clone, Debug, PartialEq, Eq)]
1499pub struct SortedColumn {
1500 pub expr: Expr,
1502 pub order: Option<SortOrder>,
1504 pub nulls: Option<NullsOrder>,
1506}
1507
1508#[derive(Clone, Debug, PartialEq, Eq)]
1510pub struct Limit {
1511 pub expr: Expr,
1513 pub offset: Option<Expr>, }
1516
1517#[derive(Clone, Debug, PartialEq, Eq)]
1521pub enum InsertBody {
1522 Select(Box<Select>, Option<Upsert>),
1524 DefaultValues,
1526}
1527
1528#[derive(Clone, Debug, PartialEq, Eq)]
1530pub struct Set {
1531 pub col_names: DistinctNames,
1533 pub expr: Expr,
1535}
1536
1537#[derive(Clone, Debug, PartialEq, Eq)]
1540pub enum PragmaBody {
1541 Equals(PragmaValue),
1543 Call(PragmaValue),
1545}
1546
1547pub type PragmaValue = Expr; #[derive(Copy, Clone, Debug, PartialEq, Eq)]
1553pub enum TriggerTime {
1554 Before, After,
1558 InsteadOf,
1560}
1561
1562#[derive(Clone, Debug, PartialEq, Eq)]
1564pub enum TriggerEvent {
1565 Delete,
1567 Insert,
1569 Update,
1571 UpdateOf(DistinctNames),
1573}
1574
1575#[derive(Clone, Debug, PartialEq, Eq)]
1579pub enum TriggerCmd {
1580 Update {
1582 or_conflict: Option<ResolveType>,
1584 tbl_name: Name,
1586 sets: Vec<Set>,
1588 from: Option<FromClause>,
1590 where_clause: Option<Expr>,
1592 },
1593 Insert {
1595 or_conflict: Option<ResolveType>,
1597 tbl_name: Name,
1599 col_names: Option<DistinctNames>,
1601 select: Box<Select>,
1603 upsert: Option<Upsert>,
1605 returning: Option<Vec<ResultColumn>>,
1607 },
1608 Delete {
1610 tbl_name: Name,
1612 where_clause: Option<Expr>,
1614 },
1615 Select(Box<Select>),
1617}
1618
1619#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1621pub enum ResolveType {
1622 Rollback,
1624 Abort, Fail,
1628 Ignore,
1630 Replace,
1632}
1633
1634#[derive(Clone, Debug, PartialEq, Eq)]
1638pub struct With {
1639 pub recursive: bool,
1641 pub ctes: Vec<CommonTableExpr>,
1643}
1644
1645#[derive(Clone, Debug, PartialEq, Eq)]
1647pub enum Materialized {
1648 Any,
1650 Yes,
1652 No,
1654}
1655
1656#[derive(Clone, Debug, PartialEq, Eq)]
1659pub struct CommonTableExpr {
1660 pub tbl_name: Name,
1662 pub columns: Option<Vec<IndexedColumn>>, pub materialized: Materialized,
1666 pub select: Box<Select>,
1668}
1669
1670impl CommonTableExpr {
1671 pub fn add_cte(ctes: &mut Vec<Self>, cte: Self) -> Result<(), ParserError> {
1673 if ctes.iter().any(|c| c.tbl_name == cte.tbl_name) {
1674 return Err(custom_err!("duplicate WITH table name: {}", cte.tbl_name));
1675 }
1676 ctes.push(cte);
1677 Ok(())
1678 }
1679}
1680
1681#[derive(Clone, Debug, PartialEq, Eq)]
1684pub struct Type {
1685 pub name: String, pub size: Option<TypeSize>,
1689}
1690
1691#[derive(Clone, Debug, PartialEq, Eq)]
1694pub enum TypeSize {
1695 MaxSize(Box<Expr>),
1697 TypeSize(Box<Expr>, Box<Expr>),
1699}
1700
1701#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1703pub enum TransactionType {
1704 Deferred, Immediate,
1708 Exclusive,
1710}
1711
1712#[derive(Clone, Debug, PartialEq, Eq)]
1716pub struct Upsert {
1717 pub index: Option<UpsertIndex>,
1719 pub do_clause: UpsertDo,
1721 pub next: Option<Box<Upsert>>,
1723}
1724
1725#[derive(Clone, Debug, PartialEq, Eq)]
1727pub struct UpsertIndex {
1728 pub targets: Vec<SortedColumn>,
1730 pub where_clause: Option<Expr>,
1732}
1733
1734#[derive(Clone, Debug, PartialEq, Eq)]
1736pub enum UpsertDo {
1737 Set {
1739 sets: Vec<Set>,
1741 where_clause: Option<Expr>,
1743 },
1744 Nothing,
1746}
1747
1748#[derive(Clone, Debug, PartialEq, Eq)]
1750pub struct FunctionTail {
1751 pub filter_clause: Option<Box<Expr>>,
1753 pub over_clause: Option<Box<Over>>,
1755}
1756
1757#[derive(Clone, Debug, PartialEq, Eq)]
1760pub enum Over {
1761 Window(Window),
1763 Name(Name),
1765}
1766
1767#[derive(Clone, Debug, PartialEq, Eq)]
1769pub struct WindowDef {
1770 pub name: Name,
1772 pub window: Window,
1774}
1775
1776#[derive(Clone, Debug, PartialEq, Eq)]
1779pub struct Window {
1780 pub base: Option<Name>,
1782 pub partition_by: Option<Vec<Expr>>,
1784 pub order_by: Option<Vec<SortedColumn>>,
1786 pub frame_clause: Option<FrameClause>,
1788}
1789
1790#[derive(Clone, Debug, PartialEq, Eq)]
1793pub struct FrameClause {
1794 pub mode: FrameMode,
1796 pub start: FrameBound,
1798 pub end: Option<FrameBound>,
1800 pub exclude: Option<FrameExclude>,
1802}
1803
1804#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1806pub enum FrameMode {
1807 Groups,
1809 Range,
1811 Rows,
1813}
1814
1815#[derive(Clone, Debug, PartialEq, Eq)]
1817pub enum FrameBound {
1818 CurrentRow,
1820 Following(Expr),
1822 Preceding(Expr),
1824 UnboundedFollowing,
1826 UnboundedPreceding,
1828}
1829
1830#[derive(Clone, Debug, PartialEq, Eq)]
1832pub enum FrameExclude {
1833 NoOthers,
1835 CurrentRow,
1837 Group,
1839 Ties,
1841}
1842
1843#[cfg(test)]
1844mod test {
1845 use super::Name;
1846
1847 #[test]
1848 fn test_dequote() {
1849 assert_eq!(name("x"), "x");
1850 assert_eq!(name("`x`"), "x");
1851 assert_eq!(name("`x``y`"), "x`y");
1852 assert_eq!(name(r#""x""#), "x");
1853 assert_eq!(name(r#""x""y""#), "x\"y");
1854 assert_eq!(name("[x]"), "x");
1855 }
1856
1857 fn name(s: &'static str) -> Name {
1858 Name(s.to_owned())
1859 }
1860}