1#[cfg(feature = "extra_checks")]
3pub mod check;
4pub mod fmt;
5
6use std::num::ParseIntError;
7use std::ops::Deref;
8use std::str::{self, Bytes, FromStr as _};
9
10#[cfg(feature = "extra_checks")]
11use check::ColumnCount;
12use fmt::TokenStream;
13use indexmap::{IndexMap, IndexSet};
14
15use crate::custom_err;
16use crate::dialect::TokenType::{self, *};
17use crate::dialect::{from_token, is_identifier, Token};
18use crate::parser::{parse::YYCODETYPE, ParserError};
19
20#[derive(Default)]
22pub struct ParameterInfo {
23 pub count: u16,
25 pub names: IndexSet<String>,
27}
28
29impl TokenStream for ParameterInfo {
31 type Error = ParseIntError;
32
33 fn append(&mut self, ty: TokenType, value: Option<&str>) -> Result<(), Self::Error> {
34 if ty == TK_VARIABLE {
35 if let Some(variable) = value {
36 if variable == "?" {
37 self.count = self.count.saturating_add(1);
38 } else if variable.as_bytes()[0] == b'?' {
39 let n = u16::from_str(&variable[1..])?;
40 if n > self.count {
41 self.count = n;
42 }
43 } else if self.names.insert(variable.to_owned()) {
44 self.count = self.count.saturating_add(1);
45 }
46 }
47 }
48 Ok(())
49 }
50}
51
52#[derive(Clone, Debug, PartialEq, Eq)]
55pub enum Cmd {
56 Explain(Stmt),
58 ExplainQueryPlan(Stmt),
60 Stmt(Stmt),
62}
63
64pub(crate) enum ExplainKind {
65 Explain,
66 QueryPlan,
67}
68
69#[derive(Clone, Debug, PartialEq, Eq)]
72pub enum Stmt {
73 AlterTable(QualifiedName, AlterTableBody),
75 Analyze(Option<QualifiedName>),
77 Attach {
79 expr: Expr,
82 db_name: Expr,
84 key: Option<Expr>,
86 },
87 Begin(Option<TransactionType>, Option<Name>),
89 Commit(Option<Name>), CreateIndex {
93 unique: bool,
95 if_not_exists: bool,
97 idx_name: QualifiedName,
99 tbl_name: Name,
101 columns: Vec<SortedColumn>,
103 where_clause: Option<Expr>,
105 },
106 CreateTable {
108 temporary: bool, if_not_exists: bool,
112 tbl_name: QualifiedName,
114 body: CreateTableBody,
116 },
117 CreateTrigger {
119 temporary: bool,
121 if_not_exists: bool,
123 trigger_name: QualifiedName,
125 time: Option<TriggerTime>,
127 event: TriggerEvent,
129 tbl_name: QualifiedName,
131 for_each_row: bool,
133 when_clause: Option<Expr>,
135 commands: Vec<TriggerCmd>,
137 },
138 CreateView {
140 temporary: bool,
142 if_not_exists: bool,
144 view_name: QualifiedName,
146 columns: Option<Vec<IndexedColumn>>, select: Box<Select>,
150 },
151 CreateVirtualTable {
153 if_not_exists: bool,
155 tbl_name: QualifiedName,
157 module_name: Name,
159 args: Option<Vec<Box<str>>>,
161 },
162 Delete {
164 with: Option<With>, tbl_name: QualifiedName,
168 indexed: Option<Indexed>,
170 where_clause: Option<Expr>,
172 returning: Option<Vec<ResultColumn>>,
174 order_by: Option<Vec<SortedColumn>>,
176 limit: Option<Limit>,
178 },
179 Detach(Expr), DropIndex {
183 if_exists: bool,
185 idx_name: QualifiedName,
187 },
188 DropTable {
190 if_exists: bool,
192 tbl_name: QualifiedName,
194 },
195 DropTrigger {
197 if_exists: bool,
199 trigger_name: QualifiedName,
201 },
202 DropView {
204 if_exists: bool,
206 view_name: QualifiedName,
208 },
209 Insert {
211 with: Option<With>, or_conflict: Option<ResolveType>, tbl_name: QualifiedName,
217 columns: Option<DistinctNames>,
219 body: InsertBody,
221 returning: Option<Vec<ResultColumn>>,
223 },
224 Pragma(QualifiedName, Option<PragmaBody>),
226 Reindex {
228 obj_name: Option<QualifiedName>,
230 },
231 Release(Name), Rollback {
235 tx_name: Option<Name>,
237 savepoint_name: Option<Name>, },
240 Savepoint(Name),
242 Select(Box<Select>),
244 Update {
246 with: Option<With>, or_conflict: Option<ResolveType>,
250 tbl_name: QualifiedName,
252 indexed: Option<Indexed>,
254 sets: Vec<Set>, from: Option<FromClause>,
258 where_clause: Option<Expr>,
260 returning: Option<Vec<ResultColumn>>,
262 order_by: Option<Vec<SortedColumn>>,
264 limit: Option<Limit>,
266 },
267 Vacuum(Option<Name>, Option<Expr>),
269}
270
271impl Stmt {
272 pub fn create_index(
274 unique: bool,
275 if_not_exists: bool,
276 idx_name: QualifiedName,
277 tbl_name: Name,
278 columns: Vec<SortedColumn>,
279 where_clause: Option<Expr>,
280 ) -> Result<Self, ParserError> {
281 has_explicit_nulls(&columns)?;
282 Ok(Self::CreateIndex {
283 unique,
284 if_not_exists,
285 idx_name,
286 tbl_name,
287 columns,
288 where_clause,
289 })
290 }
291 #[allow(clippy::too_many_arguments)]
293 pub fn update(
294 with: Option<With>,
295 or_conflict: Option<ResolveType>,
296 tbl_name: QualifiedName,
297 indexed: Option<Indexed>,
298 sets: Vec<Set>, from: Option<FromClause>,
300 where_clause: Option<Expr>,
301 returning: Option<Vec<ResultColumn>>,
302 order_by: Option<Vec<SortedColumn>>,
303 limit: Option<Limit>,
304 ) -> Result<Self, ParserError> {
305 #[cfg(feature = "extra_checks")]
306 if let Some(FromClause {
307 select: Some(ref select),
308 ref joins,
309 ..
310 }) = from
311 {
312 if matches!(select.as_ref(),
313 SelectTable::Table(qn, _, _) | SelectTable::TableCall(qn, _, _)
314 if *qn == tbl_name)
315 || joins.as_ref().is_some_and(|js| js.iter().any(|j|
316 matches!(j.table, SelectTable::Table(ref qn, _, _) | SelectTable::TableCall(ref qn, _, _)
317 if *qn == tbl_name)))
318 {
319 return Err(custom_err!(
320 "target object/alias may not appear in FROM clause",
321 ));
322 }
323 }
324 #[cfg(feature = "extra_checks")]
325 if order_by.is_some() && limit.is_none() {
326 return Err(custom_err!("ORDER BY without LIMIT on UPDATE"));
327 }
328 Ok(Self::Update {
329 with,
330 or_conflict,
331 tbl_name,
332 indexed,
333 sets,
334 from,
335 where_clause,
336 returning,
337 order_by,
338 limit,
339 })
340 }
341}
342
343#[derive(Clone, Debug, PartialEq, Eq)]
346pub enum Expr {
347 Between {
349 lhs: Box<Self>,
351 not: bool,
353 start: Box<Self>,
355 end: Box<Self>,
357 },
358 Binary(Box<Self>, Operator, Box<Self>),
360 Case {
362 base: Option<Box<Self>>,
364 when_then_pairs: Vec<(Self, Self)>,
366 else_expr: Option<Box<Self>>,
368 },
369 Cast {
371 expr: Box<Self>,
373 type_name: Option<Type>,
375 },
376 Collate(Box<Self>, Box<str>),
378 DoublyQualified(Name, Name, Name),
380 Exists(Box<Select>),
382 FunctionCall {
384 name: Id,
386 distinctness: Option<Distinctness>,
388 args: Option<Vec<Self>>,
390 order_by: Option<FunctionCallOrder>,
392 filter_over: Option<FunctionTail>,
394 },
395 FunctionCallStar {
397 name: Id,
399 filter_over: Option<FunctionTail>,
401 },
402 Id(Id),
404 InList {
406 lhs: Box<Self>,
408 not: bool,
410 rhs: Option<Vec<Self>>,
412 },
413 InSelect {
415 lhs: Box<Self>,
417 not: bool,
419 rhs: Box<Select>,
421 },
422 InTable {
424 lhs: Box<Self>,
426 not: bool,
428 rhs: QualifiedName,
430 args: Option<Vec<Self>>,
432 },
433 IsNull(Box<Self>),
435 Like {
437 lhs: Box<Self>,
439 not: bool,
441 op: LikeOperator,
443 rhs: Box<Self>,
445 escape: Option<Box<Self>>,
447 },
448 Literal(Literal),
450 Name(Name),
452 NotNull(Box<Self>),
454 Parenthesized(Vec<Self>),
456 Qualified(Name, Name),
458 Raise(ResolveType, Option<Box<Self>>),
460 Subquery(Box<Select>),
462 Unary(UnaryOperator, Box<Self>),
464 Variable(Box<str>),
466}
467
468#[derive(Clone, Debug, PartialEq, Eq)]
470pub enum FunctionCallOrder {
471 SortList(Vec<SortedColumn>),
473 #[cfg(feature = "SQLITE_ENABLE_ORDERED_SET_AGGREGATES")]
475 WithinGroup(Box<Expr>),
476}
477
478impl FunctionCallOrder {
479 #[cfg(feature = "SQLITE_ENABLE_ORDERED_SET_AGGREGATES")]
481 pub fn within_group(expr: Expr) -> Self {
482 Self::WithinGroup(Box::new(expr))
483 }
484}
485
486impl Expr {
487 pub fn parenthesized(x: Self) -> Self {
489 Self::Parenthesized(vec![x])
490 }
491 pub fn id(xt: YYCODETYPE, x: Token) -> Self {
493 Self::Id(Id::from_token(xt, x))
494 }
495 pub fn collate(x: Self, ct: YYCODETYPE, c: Token) -> Self {
497 Self::Collate(Box::new(x), from_token(ct, c))
498 }
499 pub fn cast(x: Self, type_name: Option<Type>) -> Self {
501 Self::Cast {
502 expr: Box::new(x),
503 type_name,
504 }
505 }
506 pub fn binary(left: Self, op: YYCODETYPE, right: Self) -> Self {
508 Self::Binary(Box::new(left), Operator::from(op), Box::new(right))
509 }
510 pub fn ptr(left: Self, op: Token, right: Self) -> Self {
512 let mut ptr = Operator::ArrowRight;
513 if op.1 == b"->>" {
514 ptr = Operator::ArrowRightShift;
515 }
516 Self::Binary(Box::new(left), ptr, Box::new(right))
517 }
518 pub fn like(lhs: Self, not: bool, op: LikeOperator, rhs: Self, escape: Option<Self>) -> Self {
520 Self::Like {
521 lhs: Box::new(lhs),
522 not,
523 op,
524 rhs: Box::new(rhs),
525 escape: escape.map(Box::new),
526 }
527 }
528 pub fn not_null(x: Self, op: YYCODETYPE) -> Self {
530 if op == TK_ISNULL as YYCODETYPE {
531 Self::IsNull(Box::new(x))
532 } else if op == TK_NOTNULL as YYCODETYPE {
533 Self::NotNull(Box::new(x))
534 } else {
535 unreachable!()
536 }
537 }
538 pub fn unary(op: UnaryOperator, x: Self) -> Self {
540 Self::Unary(op, Box::new(x))
541 }
542 pub fn between(lhs: Self, not: bool, start: Self, end: Self) -> Self {
544 Self::Between {
545 lhs: Box::new(lhs),
546 not,
547 start: Box::new(start),
548 end: Box::new(end),
549 }
550 }
551 pub fn in_list(lhs: Self, not: bool, rhs: Option<Vec<Self>>) -> Self {
553 Self::InList {
554 lhs: Box::new(lhs),
555 not,
556 rhs,
557 }
558 }
559 pub fn in_select(lhs: Self, not: bool, rhs: Select) -> Self {
561 Self::InSelect {
562 lhs: Box::new(lhs),
563 not,
564 rhs: Box::new(rhs),
565 }
566 }
567 pub fn in_table(lhs: Self, not: bool, rhs: QualifiedName, args: Option<Vec<Self>>) -> Self {
569 Self::InTable {
570 lhs: Box::new(lhs),
571 not,
572 rhs,
573 args,
574 }
575 }
576 pub fn sub_query(query: Select) -> Self {
578 Self::Subquery(Box::new(query))
579 }
580 pub fn function_call(
582 xt: YYCODETYPE,
583 x: Token,
584 distinctness: Option<Distinctness>,
585 args: Option<Vec<Self>>,
586 order_by: Option<FunctionCallOrder>,
587 filter_over: Option<FunctionTail>,
588 ) -> Result<Self, ParserError> {
589 #[cfg(feature = "extra_checks")]
590 if let Some(Distinctness::Distinct) = distinctness {
591 if args.as_ref().map_or(0, Vec::len) != 1 {
592 return Err(custom_err!(
593 "DISTINCT aggregates must have exactly one argument"
594 ));
595 }
596 }
597 Ok(Self::FunctionCall {
598 name: Id::from_token(xt, x),
599 distinctness,
600 args,
601 order_by,
602 filter_over,
603 })
604 }
605
606 pub fn is_integer(&self) -> Option<i64> {
608 if let Self::Literal(Literal::Numeric(s)) = self {
609 i64::from_str(s).ok()
610 } else if let Self::Unary(UnaryOperator::Positive, e) = self {
611 e.is_integer()
612 } else if let Self::Unary(UnaryOperator::Negative, e) = self {
613 e.is_integer().map(i64::saturating_neg)
614 } else {
615 None
616 }
617 }
618 #[cfg(feature = "extra_checks")]
619 fn check_range(&self, term: &str, mx: u16) -> Result<(), ParserError> {
620 if let Some(i) = self.is_integer() {
621 if i < 1 || i > mx as i64 {
622 return Err(custom_err!(
623 "{} BY term out of range - should be between 1 and {}",
624 term,
625 mx
626 ));
627 }
628 }
629 Ok(())
630 }
631}
632
633#[derive(Clone, Debug, PartialEq, Eq)]
635pub enum Literal {
636 Numeric(Box<str>),
638 String(Box<str>),
641 Blob(Box<str>),
644 Keyword(Box<str>),
646 Null,
648 CurrentDate,
650 CurrentTime,
652 CurrentTimestamp,
654}
655
656impl Literal {
657 pub fn from_ctime_kw(token: Token) -> Self {
659 if b"CURRENT_DATE".eq_ignore_ascii_case(token.1) {
660 Self::CurrentDate
661 } else if b"CURRENT_TIME".eq_ignore_ascii_case(token.1) {
662 Self::CurrentTime
663 } else if b"CURRENT_TIMESTAMP".eq_ignore_ascii_case(token.1) {
664 Self::CurrentTimestamp
665 } else {
666 unreachable!()
667 }
668 }
669}
670
671#[derive(Copy, Clone, Debug, PartialEq, Eq)]
673pub enum LikeOperator {
674 Glob,
676 Like,
678 Match,
680 Regexp,
682}
683
684impl LikeOperator {
685 pub fn from_token(token_type: YYCODETYPE, token: Token) -> Self {
687 if token_type == TK_MATCH as YYCODETYPE {
688 return Self::Match;
689 } else if token_type == TK_LIKE_KW as YYCODETYPE {
690 let token = token.1;
691 if b"LIKE".eq_ignore_ascii_case(token) {
692 return Self::Like;
693 } else if b"GLOB".eq_ignore_ascii_case(token) {
694 return Self::Glob;
695 } else if b"REGEXP".eq_ignore_ascii_case(token) {
696 return Self::Regexp;
697 }
698 }
699 unreachable!()
700 }
701}
702
703#[derive(Copy, Clone, Debug, PartialEq, Eq)]
705pub enum Operator {
706 Add,
708 And,
710 ArrowRight,
712 ArrowRightShift,
714 BitwiseAnd,
716 BitwiseOr,
718 Concat,
720 Equals,
722 Divide,
724 Greater,
726 GreaterEquals,
728 Is,
730 IsNot,
732 LeftShift,
734 Less,
736 LessEquals,
738 Modulus,
740 Multiply,
742 NotEquals,
744 Or,
746 RightShift,
748 Subtract,
750}
751
752impl From<YYCODETYPE> for Operator {
753 fn from(token_type: YYCODETYPE) -> Self {
754 match token_type {
755 x if x == TK_AND as YYCODETYPE => Self::And,
756 x if x == TK_OR as YYCODETYPE => Self::Or,
757 x if x == TK_LT as YYCODETYPE => Self::Less,
758 x if x == TK_GT as YYCODETYPE => Self::Greater,
759 x if x == TK_GE as YYCODETYPE => Self::GreaterEquals,
760 x if x == TK_LE as YYCODETYPE => Self::LessEquals,
761 x if x == TK_EQ as YYCODETYPE => Self::Equals,
762 x if x == TK_NE as YYCODETYPE => Self::NotEquals,
763 x if x == TK_BITAND as YYCODETYPE => Self::BitwiseAnd,
764 x if x == TK_BITOR as YYCODETYPE => Self::BitwiseOr,
765 x if x == TK_LSHIFT as YYCODETYPE => Self::LeftShift,
766 x if x == TK_RSHIFT as YYCODETYPE => Self::RightShift,
767 x if x == TK_PLUS as YYCODETYPE => Self::Add,
768 x if x == TK_MINUS as YYCODETYPE => Self::Subtract,
769 x if x == TK_STAR as YYCODETYPE => Self::Multiply,
770 x if x == TK_SLASH as YYCODETYPE => Self::Divide,
771 x if x == TK_REM as YYCODETYPE => Self::Modulus,
772 x if x == TK_CONCAT as YYCODETYPE => Self::Concat,
773 x if x == TK_IS as YYCODETYPE => Self::Is,
774 x if x == TK_NOT as YYCODETYPE => Self::IsNot,
775 _ => unreachable!(),
776 }
777 }
778}
779
780#[derive(Copy, Clone, Debug, PartialEq, Eq)]
782pub enum UnaryOperator {
783 BitwiseNot,
785 Negative,
787 Not,
789 Positive,
791}
792
793impl From<YYCODETYPE> for UnaryOperator {
794 fn from(token_type: YYCODETYPE) -> Self {
795 match token_type {
796 x if x == TK_BITNOT as YYCODETYPE => Self::BitwiseNot,
797 x if x == TK_MINUS as YYCODETYPE => Self::Negative,
798 x if x == TK_NOT as YYCODETYPE => Self::Not,
799 x if x == TK_PLUS as YYCODETYPE => Self::Positive,
800 _ => unreachable!(),
801 }
802 }
803}
804
805#[derive(Clone, Debug, PartialEq, Eq)]
809pub struct Select {
810 pub with: Option<With>, pub body: SelectBody,
814 pub order_by: Option<Vec<SortedColumn>>, pub limit: Option<Limit>,
818}
819
820impl Select {
821 pub fn new(
823 with: Option<With>,
824 body: SelectBody,
825 order_by: Option<Vec<SortedColumn>>,
826 limit: Option<Limit>,
827 ) -> Result<Self, ParserError> {
828 let select = Self {
829 with,
830 body,
831 order_by,
832 limit,
833 };
834 #[cfg(feature = "extra_checks")]
835 if let Self {
836 order_by: Some(ref scs),
837 ..
838 } = select
839 {
840 if let ColumnCount::Fixed(n) = select.column_count() {
841 for sc in scs {
842 sc.expr.check_range("ORDER", n)?;
843 }
844 }
845 }
846 Ok(select)
847 }
848}
849
850#[derive(Clone, Debug, PartialEq, Eq)]
852pub struct SelectBody {
853 pub select: OneSelect,
855 pub compounds: Option<Vec<CompoundSelect>>,
857}
858
859impl SelectBody {
860 pub(crate) fn push(&mut self, cs: CompoundSelect) -> Result<(), ParserError> {
861 #[cfg(feature = "extra_checks")]
862 if let ColumnCount::Fixed(n) = self.select.column_count() {
863 if let ColumnCount::Fixed(m) = cs.select.column_count() {
864 if n != m {
865 return Err(custom_err!(
866 "SELECTs to the left and right of {} do not have the same number of result columns",
867 cs.operator
868 ));
869 }
870 }
871 }
872 if let Some(ref mut v) = self.compounds {
873 v.push(cs);
874 } else {
875 self.compounds = Some(vec![cs]);
876 }
877 Ok(())
878 }
879}
880
881#[derive(Clone, Debug, PartialEq, Eq)]
883pub struct CompoundSelect {
884 pub operator: CompoundOperator,
886 pub select: OneSelect,
888}
889
890#[derive(Copy, Clone, Debug, PartialEq, Eq)]
893pub enum CompoundOperator {
894 Union,
896 UnionAll,
898 Except,
900 Intersect,
902}
903
904#[derive(Clone, Debug, PartialEq, Eq)]
907pub enum OneSelect {
908 Select {
910 distinctness: Option<Distinctness>,
912 columns: Vec<ResultColumn>,
914 from: Option<FromClause>,
916 where_clause: Option<Box<Expr>>,
918 group_by: Option<Vec<Expr>>,
920 having: Option<Box<Expr>>, window_clause: Option<Vec<WindowDef>>,
924 },
925 Values(Vec<Vec<Expr>>),
927}
928
929impl OneSelect {
930 pub fn new(
932 distinctness: Option<Distinctness>,
933 columns: Vec<ResultColumn>,
934 from: Option<FromClause>,
935 where_clause: Option<Expr>,
936 group_by: Option<Vec<Expr>>,
937 having: Option<Expr>,
938 window_clause: Option<Vec<WindowDef>>,
939 ) -> Result<Self, ParserError> {
940 #[cfg(feature = "extra_checks")]
941 if from.is_none()
942 && columns
943 .iter()
944 .any(|rc| matches!(rc, ResultColumn::Star | ResultColumn::TableStar(_)))
945 {
946 return Err(custom_err!("no tables specified"));
947 }
948 let select = Self::Select {
949 distinctness,
950 columns,
951 from,
952 where_clause: where_clause.map(Box::new),
953 group_by,
954 having: having.map(Box::new),
955 window_clause,
956 };
957 #[cfg(feature = "extra_checks")]
958 if let Self::Select {
959 group_by: Some(ref gb),
960 ..
961 } = select
962 {
963 if let ColumnCount::Fixed(n) = select.column_count() {
964 for expr in gb {
965 expr.check_range("GROUP", n)?;
966 }
967 }
968 }
969 Ok(select)
970 }
971 pub fn push(values: &mut Vec<Vec<Expr>>, v: Vec<Expr>) -> Result<(), ParserError> {
973 #[cfg(feature = "extra_checks")]
974 if values[0].len() != v.len() {
975 return Err(custom_err!("all VALUES must have the same number of terms"));
976 }
977 values.push(v);
978 Ok(())
979 }
980}
981
982#[derive(Clone, Debug, PartialEq, Eq)]
985pub struct FromClause {
986 pub select: Option<Box<SelectTable>>, pub joins: Option<Vec<JoinedSelectTable>>,
990 op: Option<JoinOperator>, }
992impl FromClause {
993 pub(crate) fn empty() -> Self {
994 Self {
995 select: None,
996 joins: None,
997 op: None,
998 }
999 }
1000
1001 pub(crate) fn push(
1002 &mut self,
1003 table: SelectTable,
1004 jc: Option<JoinConstraint>,
1005 ) -> Result<(), ParserError> {
1006 let op = self.op.take();
1007 if let Some(op) = op {
1008 let jst = JoinedSelectTable {
1009 operator: op,
1010 table,
1011 constraint: jc,
1012 };
1013 if jst.operator.is_natural() && jst.constraint.is_some() {
1014 return Err(custom_err!(
1015 "a NATURAL join may not have an ON or USING clause"
1016 ));
1017 }
1018 if let Some(ref mut joins) = self.joins {
1019 joins.push(jst);
1020 } else {
1021 self.joins = Some(vec![jst]);
1022 }
1023 } else {
1024 if jc.is_some() {
1025 return Err(custom_err!("a JOIN clause is required before ON"));
1026 }
1027 debug_assert!(self.select.is_none());
1028 debug_assert!(self.joins.is_none());
1029 self.select = Some(Box::new(table));
1030 }
1031 Ok(())
1032 }
1033
1034 pub(crate) fn push_op(&mut self, op: JoinOperator) {
1035 self.op = Some(op);
1036 }
1037}
1038
1039#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1041pub enum Distinctness {
1042 Distinct,
1044 All,
1046}
1047
1048#[derive(Clone, Debug, PartialEq, Eq)]
1051pub enum ResultColumn {
1052 Expr(Expr, Option<As>),
1054 Star,
1056 TableStar(Name),
1058}
1059
1060#[derive(Clone, Debug, PartialEq, Eq)]
1062pub enum As {
1063 As(Name),
1065 Elided(Name), }
1068
1069#[derive(Clone, Debug, PartialEq, Eq)]
1072pub struct JoinedSelectTable {
1073 pub operator: JoinOperator,
1075 pub table: SelectTable,
1077 pub constraint: Option<JoinConstraint>,
1079}
1080
1081#[derive(Clone, Debug, PartialEq, Eq)]
1084pub enum SelectTable {
1085 Table(QualifiedName, Option<As>, Option<Indexed>),
1087 TableCall(QualifiedName, Option<Vec<Expr>>, Option<As>),
1089 Select(Box<Select>, Option<As>),
1091 Sub(FromClause, Option<As>),
1093}
1094
1095#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1098pub enum JoinOperator {
1099 Comma,
1101 TypedJoin(Option<JoinType>),
1103}
1104
1105impl JoinOperator {
1106 pub(crate) fn from(
1107 token: Token,
1108 n1: Option<Name>,
1109 n2: Option<Name>,
1110 ) -> Result<Self, ParserError> {
1111 Ok({
1112 let mut jt = JoinType::try_from(token.1)?;
1113 for n in [&n1, &n2].into_iter().flatten() {
1114 jt |= JoinType::try_from(n.0.as_ref().as_bytes())?;
1115 }
1116 if (jt & (JoinType::INNER | JoinType::OUTER)) == (JoinType::INNER | JoinType::OUTER)
1117 || (jt & (JoinType::OUTER | JoinType::LEFT | JoinType::RIGHT)) == JoinType::OUTER
1118 {
1119 return Err(custom_err!(
1120 "unknown join type: {} {} {}",
1121 str::from_utf8(token.1).unwrap_or("invalid utf8"),
1122 n1.as_ref().map_or("", |n| n.0.as_ref()),
1123 n2.as_ref().map_or("", |n| n.0.as_ref())
1124 ));
1125 }
1126 Self::TypedJoin(Some(jt))
1127 })
1128 }
1129 fn is_natural(&self) -> bool {
1130 match self {
1131 Self::TypedJoin(Some(jt)) => jt.contains(JoinType::NATURAL),
1132 _ => false,
1133 }
1134 }
1135}
1136
1137bitflags::bitflags! {
1139 #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1141 pub struct JoinType: u8 {
1142 const INNER = 0x01;
1144 const CROSS = 0x02;
1146 const NATURAL = 0x04;
1148 const LEFT = 0x08;
1150 const RIGHT = 0x10;
1152 const OUTER = 0x20;
1154 }
1155}
1156
1157impl TryFrom<&[u8]> for JoinType {
1158 type Error = ParserError;
1159 fn try_from(s: &[u8]) -> Result<Self, ParserError> {
1160 if b"CROSS".eq_ignore_ascii_case(s) {
1161 Ok(Self::INNER | Self::CROSS)
1162 } else if b"FULL".eq_ignore_ascii_case(s) {
1163 Ok(Self::LEFT | Self::RIGHT | Self::OUTER)
1164 } else if b"INNER".eq_ignore_ascii_case(s) {
1165 Ok(Self::INNER)
1166 } else if b"LEFT".eq_ignore_ascii_case(s) {
1167 Ok(Self::LEFT | Self::OUTER)
1168 } else if b"NATURAL".eq_ignore_ascii_case(s) {
1169 Ok(Self::NATURAL)
1170 } else if b"RIGHT".eq_ignore_ascii_case(s) {
1171 Ok(Self::RIGHT | Self::OUTER)
1172 } else if b"OUTER".eq_ignore_ascii_case(s) {
1173 Ok(Self::OUTER)
1174 } else {
1175 Err(custom_err!(
1176 "unknown join type: {}",
1177 str::from_utf8(s).unwrap_or("invalid utf8")
1178 ))
1179 }
1180 }
1181}
1182
1183#[derive(Clone, Debug, PartialEq, Eq)]
1185pub enum JoinConstraint {
1186 On(Expr),
1188 Using(DistinctNames),
1190}
1191
1192#[derive(Clone, Debug, PartialEq, Eq)]
1194pub struct Id(pub Box<str>);
1195
1196impl Id {
1197 pub fn from_token(ty: YYCODETYPE, token: Token) -> Self {
1199 Self(from_token(ty, token))
1200 }
1201}
1202
1203#[derive(Clone, Debug, Eq)]
1207pub struct Name(pub Box<str>); pub(crate) fn unquote(s: &str) -> (&str, u8) {
1210 if s.is_empty() {
1211 return (s, 0);
1212 }
1213 let bytes = s.as_bytes();
1214 let mut quote = bytes[0];
1215 if quote != b'"' && quote != b'`' && quote != b'\'' && quote != b'[' {
1216 return (s, 0);
1217 } else if quote == b'[' {
1218 quote = b']';
1219 }
1220 debug_assert!(bytes.len() > 1);
1221 debug_assert_eq!(quote, bytes[bytes.len() - 1]);
1222 let sub = &s[1..bytes.len() - 1];
1223 if quote == b']' || sub.len() < 2 {
1224 (sub, 0)
1225 } else {
1226 (sub, quote)
1227 }
1228}
1229
1230impl Name {
1231 pub fn from_token(ty: YYCODETYPE, token: Token) -> Self {
1233 Self(from_token(ty, token))
1234 }
1235
1236 fn as_bytes(&self) -> QuotedIterator<'_> {
1237 let (sub, quote) = unquote(self.0.as_ref());
1238 QuotedIterator(sub.bytes(), quote)
1239 }
1240 #[cfg(feature = "extra_checks")]
1241 fn is_reserved(&self) -> bool {
1242 let bytes = self.as_bytes();
1243 let reserved = QuotedIterator("sqlite_".bytes(), 0);
1244 bytes.zip(reserved).fold(0u8, |acc, (b1, b2)| {
1245 acc + if b1.eq_ignore_ascii_case(&b2) { 1 } else { 0 }
1246 }) == 7u8
1247 }
1248}
1249
1250struct QuotedIterator<'s>(Bytes<'s>, u8);
1251impl Iterator for QuotedIterator<'_> {
1252 type Item = u8;
1253
1254 fn next(&mut self) -> Option<u8> {
1255 match self.0.next() {
1256 x @ Some(b) => {
1257 if b == self.1 && self.0.next() != Some(self.1) {
1258 panic!("Malformed string literal: {:?}", self.0);
1259 }
1260 x
1261 }
1262 x => x,
1263 }
1264 }
1265
1266 fn size_hint(&self) -> (usize, Option<usize>) {
1267 if self.1 == 0 {
1268 return self.0.size_hint();
1269 }
1270 (0, None)
1271 }
1272}
1273
1274fn eq_ignore_case_and_quote(mut it: QuotedIterator<'_>, mut other: QuotedIterator<'_>) -> bool {
1275 loop {
1276 match (it.next(), other.next()) {
1277 (Some(b1), Some(b2)) => {
1278 if !b1.eq_ignore_ascii_case(&b2) {
1279 return false;
1280 }
1281 }
1282 (None, None) => break,
1283 _ => return false,
1284 }
1285 }
1286 true
1287}
1288
1289impl std::hash::Hash for Name {
1291 fn hash<H: std::hash::Hasher>(&self, hasher: &mut H) {
1292 self.as_bytes()
1293 .for_each(|b| hasher.write_u8(b.to_ascii_lowercase()));
1294 }
1295}
1296impl PartialEq for Name {
1298 fn eq(&self, other: &Self) -> bool {
1299 eq_ignore_case_and_quote(self.as_bytes(), other.as_bytes())
1300 }
1301}
1302impl PartialEq<str> for Name {
1304 fn eq(&self, other: &str) -> bool {
1305 eq_ignore_case_and_quote(self.as_bytes(), QuotedIterator(other.bytes(), 0u8))
1306 }
1307}
1308impl PartialEq<&str> for Name {
1310 fn eq(&self, other: &&str) -> bool {
1311 eq_ignore_case_and_quote(self.as_bytes(), QuotedIterator(other.bytes(), 0u8))
1312 }
1313}
1314
1315#[derive(Clone, Debug, PartialEq, Eq)]
1317pub struct QualifiedName {
1318 pub db_name: Option<Name>,
1320 pub name: Name,
1322 pub alias: Option<Name>, }
1325
1326impl QualifiedName {
1327 pub fn single(name: Name) -> Self {
1329 Self {
1330 db_name: None,
1331 name,
1332 alias: None,
1333 }
1334 }
1335 pub fn fullname(db_name: Name, name: Name) -> Self {
1337 Self {
1338 db_name: Some(db_name),
1339 name,
1340 alias: None,
1341 }
1342 }
1343 pub fn xfullname(db_name: Name, name: Name, alias: Name) -> Self {
1345 Self {
1346 db_name: Some(db_name),
1347 name,
1348 alias: Some(alias),
1349 }
1350 }
1351 pub fn alias(name: Name, alias: Name) -> Self {
1353 Self {
1354 db_name: None,
1355 name,
1356 alias: Some(alias),
1357 }
1358 }
1359}
1360
1361#[derive(Clone, Debug, PartialEq, Eq)]
1363pub struct DistinctNames(IndexSet<Name>);
1364
1365impl DistinctNames {
1366 pub fn new(name: Name) -> Self {
1368 let mut dn = Self(IndexSet::new());
1369 dn.0.insert(name);
1370 dn
1371 }
1372 pub fn single(name: Name) -> Self {
1374 let mut dn = Self(IndexSet::with_capacity(1));
1375 dn.0.insert(name);
1376 dn
1377 }
1378 pub fn insert(&mut self, name: Name) -> Result<(), ParserError> {
1380 if self.0.contains(&name) {
1381 return Err(custom_err!("column \"{}\" specified more than once", name));
1382 }
1383 self.0.insert(name);
1384 Ok(())
1385 }
1386}
1387impl Deref for DistinctNames {
1388 type Target = IndexSet<Name>;
1389
1390 fn deref(&self) -> &IndexSet<Name> {
1391 &self.0
1392 }
1393}
1394
1395#[derive(Clone, Debug, PartialEq, Eq)]
1398pub enum AlterTableBody {
1399 RenameTo(Name),
1401 AddColumn(ColumnDefinition), DropColumnNotNull(Name), SetColumnNotNull(Name, Option<ResolveType>), RenameColumn {
1409 old: Name,
1411 new: Name,
1413 },
1414 DropColumn(Name), AddConstraint(NamedTableConstraint), DropConstraint(Name),
1420}
1421
1422bitflags::bitflags! {
1423 #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1425 pub struct TabFlags: u32 {
1426 const HasHidden = 0x00000002;
1429 const HasPrimaryKey = 0x00000004;
1431 const Autoincrement = 0x00000008;
1433 const HasVirtual = 0x00000020;
1436 const HasStored = 0x00000040;
1438 const HasGenerated = 0x00000060;
1440 const WithoutRowid = 0x00000080;
1442 const HasNotNull = 0x00000800;
1449 const Strict = 0x00010000;
1455 }
1456}
1457
1458#[derive(Clone, Debug, PartialEq, Eq)]
1462pub enum CreateTableBody {
1463 ColumnsAndConstraints {
1465 columns: IndexMap<Name, ColumnDefinition>,
1467 constraints: Option<Vec<NamedTableConstraint>>,
1469 flags: TabFlags,
1471 },
1472 AsSelect(Box<Select>),
1474}
1475
1476impl CreateTableBody {
1477 pub fn columns_and_constraints(
1479 columns: IndexMap<Name, ColumnDefinition>,
1480 constraints: Option<Vec<NamedTableConstraint>>,
1481 mut flags: TabFlags,
1482 ) -> Result<Self, ParserError> {
1483 for col in columns.values() {
1484 if col.flags.contains(ColFlags::PRIMKEY) {
1485 flags |= TabFlags::HasPrimaryKey;
1486 }
1487 }
1488 if let Some(ref constraints) = constraints {
1489 for c in constraints {
1490 if let NamedTableConstraint {
1491 constraint: TableConstraint::PrimaryKey { .. },
1492 ..
1493 } = c
1494 {
1495 if flags.contains(TabFlags::HasPrimaryKey) {
1496 #[cfg(feature = "extra_checks")]
1498 return Err(custom_err!("table has more than one primary key"));
1499 } else {
1500 flags |= TabFlags::HasPrimaryKey;
1501 }
1502 }
1503 }
1504 }
1505 Ok(Self::ColumnsAndConstraints {
1506 columns,
1507 constraints,
1508 flags,
1509 })
1510 }
1511}
1512
1513bitflags::bitflags! {
1514 #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1516 pub struct ColFlags: u16 {
1517 const PRIMKEY = 0x0001;
1519 const HASTYPE = 0x0004;
1523 const UNIQUE = 0x0008;
1525 const VIRTUAL = 0x0020;
1528 const STORED = 0x0040;
1530 const HASCOLL = 0x0200;
1534 const GENERATED = Self::STORED.bits() | Self::VIRTUAL.bits();
1537 }
1540}
1541
1542#[derive(Clone, Debug, PartialEq, Eq)]
1545pub struct ColumnDefinition {
1546 pub col_name: Name,
1548 pub col_type: Option<Type>,
1550 pub constraints: Vec<NamedColumnConstraint>,
1552 pub flags: ColFlags,
1554}
1555
1556impl ColumnDefinition {
1557 pub fn new(
1559 col_name: Name,
1560 mut col_type: Option<Type>,
1561 constraints: Vec<NamedColumnConstraint>,
1562 ) -> Result<Self, ParserError> {
1563 let mut flags = ColFlags::empty();
1564 #[allow(unused_variables)]
1565 let mut default = false;
1566 for constraint in &constraints {
1567 match &constraint.constraint {
1568 #[allow(unused_assignments)]
1569 ColumnConstraint::Default(..) => {
1570 default = true;
1571 }
1572 ColumnConstraint::Collate { .. } => {
1573 flags |= ColFlags::HASCOLL;
1574 }
1575 ColumnConstraint::Generated { typ, .. } => {
1576 flags |= ColFlags::VIRTUAL;
1577 if let Some(id) = typ {
1578 if id.0.eq_ignore_ascii_case("STORED") {
1579 flags |= ColFlags::STORED;
1580 }
1581 }
1582 }
1583 #[cfg(feature = "extra_checks")]
1584 ColumnConstraint::ForeignKey {
1585 clause:
1586 ForeignKeyClause {
1587 tbl_name, columns, ..
1588 },
1589 ..
1590 } => {
1591 if columns.as_ref().map_or(0, Vec::len) > 1 {
1593 return Err(custom_err!(
1594 "foreign key on {} should reference only one column of table {}",
1595 col_name,
1596 tbl_name
1597 ));
1598 }
1599 }
1600 #[allow(unused_variables)]
1601 ColumnConstraint::PrimaryKey { auto_increment, .. } => {
1602 #[cfg(feature = "extra_checks")]
1603 if *auto_increment
1604 && col_type.as_ref().is_none_or(|t| {
1605 !unquote(t.name.as_str()).0.eq_ignore_ascii_case("INTEGER")
1606 })
1607 {
1608 return Err(custom_err!(
1609 "AUTOINCREMENT is only allowed on an INTEGER PRIMARY KEY"
1610 ));
1611 }
1612 flags |= ColFlags::PRIMKEY | ColFlags::UNIQUE;
1613 }
1614 ColumnConstraint::Unique(..) => {
1615 flags |= ColFlags::UNIQUE;
1616 }
1617 _ => {}
1618 }
1619 }
1620 #[cfg(feature = "extra_checks")]
1621 if flags.contains(ColFlags::PRIMKEY) && flags.intersects(ColFlags::GENERATED) {
1622 return Err(custom_err!(
1623 "generated columns cannot be part of the PRIMARY KEY"
1624 ));
1625 } else if default && flags.intersects(ColFlags::GENERATED) {
1626 return Err(custom_err!("cannot use DEFAULT on a generated column"));
1627 }
1628 if flags.intersects(ColFlags::GENERATED) {
1629 if let Some(ref mut col_type) = col_type {
1631 let mut split = col_type.name.split_ascii_whitespace();
1632 if split
1633 .next_back()
1634 .is_some_and(|s| s.eq_ignore_ascii_case("ALWAYS"))
1635 && split
1636 .next_back()
1637 .is_some_and(|s| s.eq_ignore_ascii_case("GENERATED"))
1638 {
1639 let new_type: Vec<&str> = split.collect();
1641 col_type.name = new_type.join(" ");
1642 }
1643 }
1644 }
1645 if col_type.as_ref().is_some_and(|t| !t.name.is_empty()) {
1646 flags |= ColFlags::HASTYPE;
1647 }
1648 Ok(Self {
1649 col_name,
1650 col_type,
1651 constraints,
1652 flags,
1653 })
1654 }
1655 pub fn add_column(columns: &mut IndexMap<Name, Self>, cd: Self) -> Result<(), ParserError> {
1657 let col_name = &cd.col_name;
1658 if columns.contains_key(col_name) {
1659 return Err(custom_err!("duplicate column name: {}", col_name));
1660 } else if cd.flags.contains(ColFlags::PRIMKEY)
1661 && columns
1662 .values()
1663 .any(|c| c.flags.contains(ColFlags::PRIMKEY))
1664 {
1665 #[cfg(feature = "extra_checks")]
1666 return Err(custom_err!("table has more than one primary key")); }
1668 columns.insert(col_name.clone(), cd);
1669 Ok(())
1670 }
1671}
1672
1673#[derive(Clone, Debug, PartialEq, Eq)]
1676pub struct NamedColumnConstraint {
1677 pub name: Option<Name>,
1679 pub constraint: ColumnConstraint,
1681}
1682
1683#[derive(Clone, Debug, PartialEq, Eq)]
1686pub enum ColumnConstraint {
1687 PrimaryKey {
1689 order: Option<SortOrder>,
1691 conflict_clause: Option<ResolveType>,
1693 auto_increment: bool,
1695 },
1696 NotNull {
1698 nullable: bool,
1700 conflict_clause: Option<ResolveType>,
1702 },
1703 Unique(Option<ResolveType>),
1705 Check(Expr),
1707 Default(Expr),
1709 Defer(DeferSubclause), Collate {
1713 collation_name: Name, },
1716 ForeignKey {
1718 clause: ForeignKeyClause,
1720 defer_clause: Option<DeferSubclause>,
1722 },
1723 Generated {
1725 expr: Expr,
1727 typ: Option<Id>,
1729 },
1730}
1731
1732#[derive(Clone, Debug, PartialEq, Eq)]
1735pub struct NamedTableConstraint {
1736 pub name: Option<Name>,
1738 pub constraint: TableConstraint,
1740}
1741
1742#[derive(Clone, Debug, PartialEq, Eq)]
1745pub enum TableConstraint {
1746 PrimaryKey {
1748 columns: Vec<SortedColumn>,
1750 auto_increment: bool,
1752 conflict_clause: Option<ResolveType>,
1754 },
1755 Unique {
1757 columns: Vec<SortedColumn>,
1759 conflict_clause: Option<ResolveType>,
1761 },
1762 Check(Expr, Option<ResolveType>),
1764 ForeignKey {
1766 columns: Vec<IndexedColumn>,
1768 clause: ForeignKeyClause,
1770 defer_clause: Option<DeferSubclause>,
1772 },
1773}
1774
1775impl TableConstraint {
1776 pub fn primary_key(
1778 columns: Vec<SortedColumn>,
1779 auto_increment: bool,
1780 conflict_clause: Option<ResolveType>,
1781 ) -> Result<Self, ParserError> {
1782 has_expression(&columns)?;
1783 has_explicit_nulls(&columns)?;
1784 Ok(Self::PrimaryKey {
1785 columns,
1786 auto_increment,
1787 conflict_clause,
1788 })
1789 }
1790 pub fn unique(
1792 columns: Vec<SortedColumn>,
1793 conflict_clause: Option<ResolveType>,
1794 ) -> Result<Self, ParserError> {
1795 has_expression(&columns)?;
1796 has_explicit_nulls(&columns)?;
1797 Ok(Self::Unique {
1798 columns,
1799 conflict_clause,
1800 })
1801 }
1802}
1803
1804#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1806pub enum SortOrder {
1807 Asc,
1809 Desc,
1811}
1812
1813#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1815pub enum NullsOrder {
1816 First,
1818 Last,
1820}
1821
1822#[derive(Clone, Debug, PartialEq, Eq)]
1825pub struct ForeignKeyClause {
1826 pub tbl_name: Name,
1828 pub columns: Option<Vec<IndexedColumn>>,
1830 pub args: Vec<RefArg>,
1832}
1833
1834#[derive(Clone, Debug, PartialEq, Eq)]
1836pub enum RefArg {
1837 OnDelete(RefAct),
1839 OnInsert(RefAct),
1841 OnUpdate(RefAct),
1843 Match(Name),
1845}
1846
1847#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1849pub enum RefAct {
1850 SetNull,
1852 SetDefault,
1854 Cascade,
1856 Restrict,
1858 NoAction,
1860}
1861
1862#[derive(Clone, Debug, PartialEq, Eq)]
1864pub struct DeferSubclause {
1865 pub deferrable: bool,
1867 pub init_deferred: Option<InitDeferredPred>,
1869}
1870
1871#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1873pub enum InitDeferredPred {
1874 InitiallyDeferred,
1876 InitiallyImmediate, }
1879
1880#[derive(Clone, Debug, PartialEq, Eq)]
1883pub struct IndexedColumn {
1884 pub col_name: Name,
1886 pub collation_name: Option<Name>, pub order: Option<SortOrder>,
1890}
1891
1892#[derive(Clone, Debug, PartialEq, Eq)]
1894pub enum Indexed {
1895 IndexedBy(Name),
1897 NotIndexed,
1899}
1900
1901#[derive(Clone, Debug, PartialEq, Eq)]
1903pub struct SortedColumn {
1904 pub expr: Expr,
1906 pub order: Option<SortOrder>,
1908 pub nulls: Option<NullsOrder>,
1910}
1911
1912fn has_expression(columns: &Vec<SortedColumn>) -> Result<(), ParserError> {
1913 for _column in columns {
1914 if false {
1915 return Err(custom_err!(
1916 "expressions prohibited in PRIMARY KEY and UNIQUE constraints"
1917 ));
1918 }
1919 }
1920 Ok(())
1921}
1922#[allow(unused_variables)]
1923fn has_explicit_nulls(columns: &[SortedColumn]) -> Result<(), ParserError> {
1924 #[cfg(feature = "extra_checks")]
1925 for column in columns {
1926 if let Some(ref nulls) = column.nulls {
1927 return Err(custom_err!(
1928 "unsupported use of NULLS {}",
1929 if *nulls == NullsOrder::First {
1930 "FIRST"
1931 } else {
1932 "LAST"
1933 }
1934 ));
1935 }
1936 }
1937 Ok(())
1938}
1939
1940#[derive(Clone, Debug, PartialEq, Eq)]
1942pub struct Limit {
1943 pub expr: Expr,
1945 pub offset: Option<Expr>, }
1948
1949#[derive(Clone, Debug, PartialEq, Eq)]
1953pub enum InsertBody {
1954 Select(Box<Select>, Option<Box<Upsert>>),
1956 DefaultValues,
1958}
1959
1960#[derive(Clone, Debug, PartialEq, Eq)]
1962pub struct Set {
1963 pub col_names: DistinctNames,
1965 pub expr: Expr,
1967}
1968
1969#[derive(Clone, Debug, PartialEq, Eq)]
1972pub enum PragmaBody {
1973 Equals(PragmaValue),
1975 Call(PragmaValue),
1977}
1978
1979pub type PragmaValue = Expr; #[derive(Copy, Clone, Debug, PartialEq, Eq)]
1985pub enum TriggerTime {
1986 Before, After,
1990 InsteadOf,
1992}
1993
1994#[derive(Clone, Debug, PartialEq, Eq)]
1996pub enum TriggerEvent {
1997 Delete,
1999 Insert,
2001 Update,
2003 UpdateOf(DistinctNames),
2005}
2006
2007#[derive(Clone, Debug, PartialEq, Eq)]
2011pub enum TriggerCmd {
2012 Update {
2014 or_conflict: Option<ResolveType>,
2016 tbl_name: QualifiedName,
2018 sets: Vec<Set>, from: Option<FromClause>,
2022 where_clause: Option<Expr>,
2024 },
2025 Insert {
2027 or_conflict: Option<ResolveType>,
2029 tbl_name: QualifiedName,
2031 col_names: Option<DistinctNames>,
2033 select: Box<Select>,
2035 upsert: Option<Box<Upsert>>,
2037 },
2038 Delete {
2040 tbl_name: QualifiedName,
2042 where_clause: Option<Expr>,
2044 },
2045 Select(Box<Select>),
2047}
2048
2049#[derive(Copy, Clone, Debug, PartialEq, Eq)]
2051pub enum ResolveType {
2052 Rollback,
2054 Abort, Fail,
2058 Ignore,
2060 Replace,
2062}
2063
2064#[derive(Clone, Debug, PartialEq, Eq)]
2068pub struct With {
2069 pub recursive: bool,
2071 pub ctes: Vec<CommonTableExpr>,
2073}
2074
2075#[derive(Clone, Debug, PartialEq, Eq)]
2077pub enum Materialized {
2078 Any,
2080 Yes,
2082 No,
2084}
2085
2086#[derive(Clone, Debug, PartialEq, Eq)]
2089pub struct CommonTableExpr {
2090 pub tbl_name: Name,
2092 pub columns: Option<Vec<IndexedColumn>>, pub materialized: Materialized,
2096 pub select: Box<Select>,
2098}
2099
2100impl CommonTableExpr {
2101 pub fn new(
2103 tbl_name: Name,
2104 columns: Option<Vec<IndexedColumn>>,
2105 materialized: Materialized,
2106 select: Select,
2107 ) -> Result<Self, ParserError> {
2108 #[cfg(feature = "extra_checks")]
2109 if let Some(ref columns) = columns {
2110 if let check::ColumnCount::Fixed(cc) = select.column_count() {
2111 if cc as usize != columns.len() {
2112 return Err(custom_err!(
2113 "table {} has {} values for {} columns",
2114 tbl_name,
2115 cc,
2116 columns.len()
2117 ));
2118 }
2119 }
2120 }
2121 Ok(Self {
2122 tbl_name,
2123 columns,
2124 materialized,
2125 select: Box::new(select),
2126 })
2127 }
2128 pub fn add_cte(ctes: &mut Vec<Self>, cte: Self) -> Result<(), ParserError> {
2130 #[cfg(feature = "extra_checks")]
2131 if ctes.iter().any(|c| c.tbl_name == cte.tbl_name) {
2132 return Err(custom_err!("duplicate WITH table name: {}", cte.tbl_name));
2133 }
2134 ctes.push(cte);
2135 Ok(())
2136 }
2137}
2138
2139#[derive(Clone, Debug, PartialEq, Eq)]
2142pub struct Type {
2143 pub name: String, pub size: Option<TypeSize>,
2147}
2148
2149#[derive(Clone, Debug, PartialEq, Eq)]
2152pub enum TypeSize {
2153 MaxSize(Box<Expr>),
2155 TypeSize(Box<Expr>, Box<Expr>),
2157}
2158
2159#[derive(Copy, Clone, Debug, PartialEq, Eq)]
2161pub enum TransactionType {
2162 Deferred, Immediate,
2166 Exclusive,
2168}
2169
2170#[derive(Clone, Debug, PartialEq, Eq)]
2174pub struct Upsert {
2175 pub index: Option<UpsertIndex>,
2177 pub do_clause: UpsertDo,
2179 pub next: Option<Box<Self>>,
2181}
2182
2183#[derive(Clone, Debug, PartialEq, Eq)]
2185pub struct UpsertIndex {
2186 pub targets: Vec<SortedColumn>,
2188 pub where_clause: Option<Expr>,
2190}
2191
2192impl UpsertIndex {
2193 pub fn new(
2195 targets: Vec<SortedColumn>,
2196 where_clause: Option<Expr>,
2197 ) -> Result<Self, ParserError> {
2198 has_explicit_nulls(&targets)?;
2199 Ok(Self {
2200 targets,
2201 where_clause,
2202 })
2203 }
2204}
2205
2206#[derive(Clone, Debug, PartialEq, Eq)]
2208pub enum UpsertDo {
2209 Set {
2211 sets: Vec<Set>,
2213 where_clause: Option<Expr>,
2215 },
2216 Nothing,
2218}
2219
2220#[derive(Clone, Debug, PartialEq, Eq)]
2222pub struct FunctionTail {
2223 pub filter_clause: Option<Box<Expr>>,
2225 pub over_clause: Option<Box<Over>>,
2227}
2228
2229#[derive(Clone, Debug, PartialEq, Eq)]
2232pub enum Over {
2233 Window(Box<Window>),
2235 Name(Name),
2237}
2238
2239#[derive(Clone, Debug, PartialEq, Eq)]
2241pub struct WindowDef {
2242 pub name: Name,
2244 pub window: Window,
2246}
2247
2248#[derive(Clone, Debug, PartialEq, Eq)]
2251pub struct Window {
2252 pub base: Option<Name>,
2254 pub partition_by: Option<Vec<Expr>>,
2256 pub order_by: Option<Vec<SortedColumn>>,
2258 pub frame_clause: Option<FrameClause>,
2260}
2261
2262#[derive(Clone, Debug, PartialEq, Eq)]
2265pub struct FrameClause {
2266 pub mode: FrameMode,
2268 pub start: FrameBound,
2270 pub end: Option<FrameBound>,
2272 pub exclude: Option<FrameExclude>,
2274}
2275
2276#[derive(Copy, Clone, Debug, PartialEq, Eq)]
2278pub enum FrameMode {
2279 Groups,
2281 Range,
2283 Rows,
2285}
2286
2287#[derive(Clone, Debug, PartialEq, Eq)]
2289pub enum FrameBound {
2290 CurrentRow,
2292 Following(Expr),
2294 Preceding(Expr),
2296 UnboundedFollowing,
2298 UnboundedPreceding,
2300}
2301
2302#[derive(Clone, Debug, PartialEq, Eq)]
2304pub enum FrameExclude {
2305 NoOthers,
2307 CurrentRow,
2309 Group,
2311 Ties,
2313}
2314
2315#[cfg(test)]
2316mod test {
2317 use super::Name;
2318
2319 #[test]
2320 fn test_dequote() {
2321 assert_eq!(name("x"), "x");
2322 assert_eq!(name("`x`"), "x");
2323 assert_eq!(name("`x``y`"), "x`y");
2324 assert_eq!(name(r#""x""#), "x");
2325 assert_eq!(name(r#""x""y""#), "x\"y");
2326 assert_eq!(name("[x]"), "x");
2327 }
2328
2329 fn name(s: &'static str) -> Name {
2330 Name(s.into())
2331 }
2332}