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
10use bumpalo::{collections::Vec, Bump};
11#[cfg(feature = "serde")]
12use serde::Serialize;
13
14#[cfg(feature = "extra_checks")]
15use check::ColumnCount;
16use fmt::TokenStream;
17
18use crate::custom_err;
19use crate::dialect::TokenType::{self, *};
20use crate::dialect::{from_token, is_identifier, Token};
21use crate::parser::{parse::YYCODETYPE, ParserError};
22
23#[derive(Default)]
25pub struct ParameterInfo {
26 pub count: u16,
28 pub names: indexmap::IndexSet<String>,
30}
31
32impl TokenStream for ParameterInfo {
34 type Error = ParseIntError;
35
36 fn append(&mut self, ty: TokenType, value: Option<&str>) -> Result<(), Self::Error> {
37 if ty == TK_VARIABLE {
38 if let Some(variable) = value {
39 if variable == "?" {
40 self.count = self.count.saturating_add(1);
41 } else if variable.as_bytes()[0] == b'?' {
42 let n = u16::from_str(&variable[1..])?;
43 if n > self.count {
44 self.count = n;
45 }
46 } else if self.names.insert(variable.to_owned()) {
47 self.count = self.count.saturating_add(1);
48 }
49 }
50 }
51 Ok(())
52 }
53}
54
55#[derive(Debug, PartialEq, Eq)]
58#[cfg_attr(feature = "serde", derive(Serialize))]
59pub enum Cmd<'bump> {
60 Explain(Stmt<'bump>),
62 ExplainQueryPlan(Stmt<'bump>),
64 Stmt(Stmt<'bump>),
66}
67
68pub(crate) enum ExplainKind {
69 Explain,
70 QueryPlan,
71}
72
73#[derive(Debug, PartialEq, Eq)]
76#[cfg_attr(feature = "serde", derive(Serialize))]
77pub enum Stmt<'bump> {
78 AlterTable(QualifiedName<'bump>, AlterTableBody<'bump>),
80 Analyze(Option<QualifiedName<'bump>>),
82 Attach {
84 expr: Expr<'bump>,
87 db_name: Expr<'bump>,
89 key: Option<Expr<'bump>>,
91 },
92 Begin(Option<TransactionType>, Option<Name<'bump>>),
94 Commit(Option<Name<'bump>>), CreateIndex {
98 unique: bool,
100 if_not_exists: bool,
102 idx_name: QualifiedName<'bump>,
104 tbl_name: Name<'bump>,
106 columns: &'bump [SortedColumn<'bump>],
108 where_clause: Option<Expr<'bump>>,
110 },
111 CreateTable {
113 temporary: bool, if_not_exists: bool,
117 tbl_name: QualifiedName<'bump>,
119 body: CreateTableBody<'bump>,
121 },
122 CreateTrigger {
124 temporary: bool,
126 if_not_exists: bool,
128 trigger_name: QualifiedName<'bump>,
130 time: Option<TriggerTime>,
132 event: TriggerEvent<'bump>,
134 tbl_name: QualifiedName<'bump>,
136 for_each_row: bool,
138 when_clause: Option<Expr<'bump>>,
140 commands: &'bump [TriggerCmd<'bump>],
142 },
143 CreateView {
145 temporary: bool,
147 if_not_exists: bool,
149 view_name: QualifiedName<'bump>,
151 columns: Option<&'bump [IndexedColumn<'bump>]>, select: &'bump Select<'bump>,
155 },
156 CreateVirtualTable {
158 if_not_exists: bool,
160 tbl_name: QualifiedName<'bump>,
162 module_name: Name<'bump>,
164 args: Option<&'bump [&'bump str]>,
166 },
167 Delete {
169 with: Option<With<'bump>>, tbl_name: QualifiedName<'bump>,
173 indexed: Option<Indexed<'bump>>,
175 where_clause: Option<Expr<'bump>>,
177 returning: Option<&'bump [ResultColumn<'bump>]>,
179 order_by: Option<&'bump [SortedColumn<'bump>]>,
181 limit: Option<&'bump Limit<'bump>>,
183 },
184 Detach(Expr<'bump>), DropIndex {
188 if_exists: bool,
190 idx_name: QualifiedName<'bump>,
192 },
193 DropTable {
195 if_exists: bool,
197 tbl_name: QualifiedName<'bump>,
199 },
200 DropTrigger {
202 if_exists: bool,
204 trigger_name: QualifiedName<'bump>,
206 },
207 DropView {
209 if_exists: bool,
211 view_name: QualifiedName<'bump>,
213 },
214 Insert {
216 with: Option<With<'bump>>, or_conflict: Option<ResolveType>, tbl_name: QualifiedName<'bump>,
222 columns: Option<DistinctNames<'bump>>,
224 body: InsertBody<'bump>,
226 returning: Option<&'bump [ResultColumn<'bump>]>,
228 },
229 Pragma(QualifiedName<'bump>, Option<PragmaBody<'bump>>),
231 Reindex {
233 obj_name: Option<QualifiedName<'bump>>,
235 },
236 Release(Name<'bump>), Rollback {
240 tx_name: Option<Name<'bump>>,
242 savepoint_name: Option<Name<'bump>>, },
245 Savepoint(Name<'bump>),
247 Select(&'bump Select<'bump>),
249 Update {
251 with: Option<With<'bump>>, or_conflict: Option<ResolveType>,
255 tbl_name: QualifiedName<'bump>,
257 indexed: Option<Indexed<'bump>>,
259 sets: &'bump [Set<'bump>], from: Option<FromClause<'bump>>,
263 where_clause: Option<Expr<'bump>>,
265 returning: Option<&'bump [ResultColumn<'bump>]>,
267 order_by: Option<&'bump [SortedColumn<'bump>]>,
269 limit: Option<&'bump Limit<'bump>>,
271 },
272 Vacuum(Option<Name<'bump>>, Option<Expr<'bump>>),
274}
275
276impl<'bump> Stmt<'bump> {
277 pub fn create_index(
279 unique: bool,
280 if_not_exists: bool,
281 idx_name: QualifiedName<'bump>,
282 tbl_name: Name<'bump>,
283 columns: Vec<'bump, SortedColumn<'bump>>,
284 where_clause: Option<Expr<'bump>>,
285 ) -> Result<Self, ParserError> {
286 has_explicit_nulls(&columns)?;
287 Ok(Self::CreateIndex {
288 unique,
289 if_not_exists,
290 idx_name,
291 tbl_name,
292 columns: columns.into_bump_slice(),
293 where_clause,
294 })
295 }
296 #[allow(clippy::too_many_arguments)]
298 pub fn update(
299 with: Option<With<'bump>>,
300 or_conflict: Option<ResolveType>,
301 tbl_name: QualifiedName<'bump>,
302 indexed: Option<Indexed<'bump>>,
303 sets: Vec<'bump, Set<'bump>>, from: Option<FromClause<'bump>>,
305 where_clause: Option<Expr<'bump>>,
306 returning: Option<Vec<'bump, ResultColumn<'bump>>>,
307 order_by: Option<Vec<'bump, SortedColumn<'bump>>>,
308 limit: Option<&'bump Limit<'bump>>,
309 ) -> Result<Self, ParserError> {
310 #[cfg(feature = "extra_checks")]
311 if let Some(FromClause {
312 select: Some(ref select),
313 ref joins,
314 ..
315 }) = from
316 {
317 if matches!(select,
318 SelectTable::Table(qn, _, _) | SelectTable::TableCall(qn, _, _)
319 if *qn == tbl_name)
320 || joins.as_ref().is_some_and(|js| js.iter().any(|j|
321 matches!(j.table, SelectTable::Table(ref qn, _, _) | SelectTable::TableCall(ref qn, _, _)
322 if *qn == tbl_name)))
323 {
324 return Err(custom_err!(
325 "target object/alias may not appear in FROM clause",
326 ));
327 }
328 }
329 #[cfg(feature = "extra_checks")]
330 if order_by.is_some() && limit.is_none() {
331 return Err(custom_err!("ORDER BY without LIMIT on UPDATE"));
332 }
333 Ok(Self::Update {
334 with,
335 or_conflict,
336 tbl_name,
337 indexed,
338 sets: sets.into_bump_slice(),
339 from,
340 where_clause,
341 returning: returning.map(|r| r.into_bump_slice()),
342 order_by: order_by.map(|ob| ob.into_bump_slice()),
343 limit,
344 })
345 }
346}
347
348#[derive(Debug, PartialEq, Eq)]
351#[cfg_attr(feature = "serde", derive(Serialize))]
352pub enum Expr<'bump> {
353 Between {
355 lhs: &'bump Expr<'bump>,
357 not: bool,
359 start: &'bump Expr<'bump>,
361 end: &'bump Expr<'bump>,
363 },
364 Binary(&'bump Expr<'bump>, Operator, &'bump Expr<'bump>),
366 Case {
368 base: Option<&'bump Expr<'bump>>,
370 when_then_pairs: &'bump [(Expr<'bump>, Expr<'bump>)],
372 else_expr: Option<&'bump Expr<'bump>>,
374 },
375 Cast {
377 expr: &'bump Expr<'bump>,
379 type_name: Option<Type<'bump>>,
381 },
382 Collate(&'bump Expr<'bump>, &'bump str),
384 DoublyQualified(Name<'bump>, Name<'bump>, Name<'bump>),
386 Exists(&'bump Select<'bump>),
388 FunctionCall {
390 name: Id<'bump>,
392 distinctness: Option<Distinctness>,
394 args: Option<&'bump [Expr<'bump>]>,
396 order_by: Option<FunctionCallOrder<'bump>>,
398 filter_over: Option<FunctionTail<'bump>>,
400 },
401 FunctionCallStar {
403 name: Id<'bump>,
405 filter_over: Option<FunctionTail<'bump>>,
407 },
408 Id(Id<'bump>),
410 InList {
412 lhs: &'bump Expr<'bump>,
414 not: bool,
416 rhs: Option<&'bump [Expr<'bump>]>,
418 },
419 InSelect {
421 lhs: &'bump Expr<'bump>,
423 not: bool,
425 rhs: &'bump Select<'bump>,
427 },
428 InTable {
430 lhs: &'bump Expr<'bump>,
432 not: bool,
434 rhs: QualifiedName<'bump>,
436 args: Option<&'bump [Expr<'bump>]>,
438 },
439 IsNull(&'bump Expr<'bump>),
441 Like {
443 lhs: &'bump Expr<'bump>,
445 not: bool,
447 op: LikeOperator,
449 rhs: &'bump Expr<'bump>,
451 escape: Option<&'bump Expr<'bump>>,
453 },
454 Literal(Literal<'bump>),
456 Name(Name<'bump>),
458 NotNull(&'bump Expr<'bump>),
460 Parenthesized(Vec<'bump, Expr<'bump>>),
462 Qualified(Name<'bump>, Name<'bump>),
464 Raise(ResolveType, Option<&'bump Expr<'bump>>),
466 Subquery(&'bump Select<'bump>),
468 Unary(UnaryOperator, &'bump Expr<'bump>),
470 Variable(&'bump str),
472}
473
474#[derive(Debug, PartialEq, Eq)]
476#[cfg_attr(feature = "serde", derive(Serialize))]
477pub enum FunctionCallOrder<'bump> {
478 SortList(&'bump [SortedColumn<'bump>]),
480 #[cfg(feature = "SQLITE_ENABLE_ORDERED_SET_AGGREGATES")]
482 WithinGroup(&'bump Expr<'bump>),
483}
484
485impl<'bump> FunctionCallOrder<'bump> {
486 #[cfg(feature = "SQLITE_ENABLE_ORDERED_SET_AGGREGATES")]
488 pub fn within_group(expr: &'bump Expr<'bump>) -> Self {
489 Self::WithinGroup(expr)
490 }
491}
492
493impl<'bump> Expr<'bump> {
494 pub fn parenthesized(x: Self, b: &'bump Bump) -> Self {
496 Self::Parenthesized(bumpalo::vec![in b; x])
497 }
498 pub fn id(xt: YYCODETYPE, x: Token, b: &'bump Bump) -> Self {
500 Self::Id(Id::from_token(xt, x, b))
501 }
502 pub fn collate(x: Self, ct: YYCODETYPE, c: Token, b: &'bump Bump) -> Self {
504 Self::Collate(b.alloc(x), from_token(ct, c, b))
505 }
506 pub fn cast(x: Self, type_name: Option<Type<'bump>>, b: &'bump Bump) -> Self {
508 Self::Cast {
509 expr: b.alloc(x),
510 type_name,
511 }
512 }
513 pub fn binary(left: Self, op: YYCODETYPE, right: Self, b: &'bump Bump) -> Self {
515 Self::Binary(b.alloc(left), Operator::from(op), b.alloc(right))
516 }
517 pub fn ptr(left: Self, op: Token, right: Self, b: &'bump Bump) -> Self {
519 let mut ptr = Operator::ArrowRight;
520 if op.1 == b"->>" {
521 ptr = Operator::ArrowRightShift;
522 }
523 Self::Binary(b.alloc(left), ptr, b.alloc(right))
524 }
525 pub fn like(
527 lhs: Self,
528 not: bool,
529 op: LikeOperator,
530 rhs: Self,
531 escape: Option<Self>,
532 b: &'bump Bump,
533 ) -> Self {
534 Self::Like {
535 lhs: b.alloc(lhs),
536 not,
537 op,
538 rhs: b.alloc(rhs),
539 escape: escape.map(|e| b.alloc(e) as _),
540 }
541 }
542 pub fn not_null(x: Self, op: YYCODETYPE, b: &'bump Bump) -> Self {
544 if op == TK_ISNULL as YYCODETYPE {
545 Self::IsNull(b.alloc(x))
546 } else if op == TK_NOTNULL as YYCODETYPE {
547 Self::NotNull(b.alloc(x))
548 } else {
549 unreachable!()
550 }
551 }
552 pub fn unary(op: UnaryOperator, x: Self, b: &'bump Bump) -> Self {
554 Self::Unary(op, b.alloc(x))
555 }
556 pub fn between(lhs: Self, not: bool, start: Self, end: Self, b: &'bump Bump) -> Self {
558 Self::Between {
559 lhs: b.alloc(lhs),
560 not,
561 start: b.alloc(start),
562 end: b.alloc(end),
563 }
564 }
565 pub fn in_list(lhs: Self, not: bool, rhs: Option<Vec<'bump, Self>>, b: &'bump Bump) -> Self {
567 Self::InList {
568 lhs: b.alloc(lhs),
569 not,
570 rhs: rhs.map(|r| r.into_bump_slice()),
571 }
572 }
573 pub fn in_select(lhs: Self, not: bool, rhs: Select<'bump>, b: &'bump Bump) -> Self {
575 Self::InSelect {
576 lhs: b.alloc(lhs),
577 not,
578 rhs: b.alloc(rhs),
579 }
580 }
581 pub fn in_table(
583 lhs: Self,
584 not: bool,
585 rhs: QualifiedName<'bump>,
586 args: Option<Vec<'bump, Self>>,
587 b: &'bump Bump,
588 ) -> Self {
589 Self::InTable {
590 lhs: b.alloc(lhs),
591 not,
592 rhs,
593 args: args.map(|a| a.into_bump_slice()),
594 }
595 }
596 pub fn sub_query(query: Select<'bump>, b: &'bump Bump) -> Self {
598 Self::Subquery(b.alloc(query))
599 }
600 pub fn function_call(
602 xt: YYCODETYPE,
603 x: Token,
604 distinctness: Option<Distinctness>,
605 args: Option<Vec<'bump, Self>>,
606 order_by: Option<FunctionCallOrder<'bump>>,
607 filter_over: Option<FunctionTail<'bump>>,
608 b: &'bump Bump,
609 ) -> Result<Self, ParserError> {
610 #[cfg(feature = "extra_checks")]
611 if let Some(Distinctness::Distinct) = distinctness {
612 if args.as_ref().map_or(0, Vec::len) != 1 {
613 return Err(custom_err!(
614 "DISTINCT aggregates must have exactly one argument"
615 ));
616 }
617 }
618 Ok(Self::FunctionCall {
619 name: Id::from_token(xt, x, b),
620 distinctness,
621 args: args.map(|a| a.into_bump_slice()),
622 order_by,
623 filter_over,
624 })
625 }
626
627 pub fn is_integer(&self) -> Option<i64> {
629 if let Self::Literal(Literal::Numeric(s)) = self {
630 i64::from_str(s).ok()
631 } else if let Self::Unary(UnaryOperator::Positive, e) = self {
632 e.is_integer()
633 } else if let Self::Unary(UnaryOperator::Negative, e) = self {
634 e.is_integer().map(i64::saturating_neg)
635 } else {
636 None
637 }
638 }
639 #[cfg(feature = "extra_checks")]
640 fn check_range(&self, term: &str, mx: u16) -> Result<(), ParserError> {
641 if let Some(i) = self.is_integer() {
642 if i < 1 || i > mx as i64 {
643 return Err(custom_err!(
644 "{} BY term out of range - should be between 1 and {}",
645 term,
646 mx
647 ));
648 }
649 }
650 Ok(())
651 }
652}
653
654#[derive(Debug, PartialEq, Eq)]
656#[cfg_attr(feature = "serde", derive(Serialize))]
657pub enum Literal<'bump> {
658 Numeric(&'bump str),
660 String(&'bump str),
663 Blob(&'bump str),
666 Keyword(&'bump str),
668 Null,
670 CurrentDate,
672 CurrentTime,
674 CurrentTimestamp,
676}
677
678impl<'bump> Literal<'bump> {
679 pub fn from_ctime_kw(token: Token) -> Self {
681 if b"CURRENT_DATE".eq_ignore_ascii_case(token.1) {
682 Self::CurrentDate
683 } else if b"CURRENT_TIME".eq_ignore_ascii_case(token.1) {
684 Self::CurrentTime
685 } else if b"CURRENT_TIMESTAMP".eq_ignore_ascii_case(token.1) {
686 Self::CurrentTimestamp
687 } else {
688 unreachable!()
689 }
690 }
691}
692
693#[derive(Copy, Clone, Debug, PartialEq, Eq)]
695#[cfg_attr(feature = "serde", derive(Serialize))]
696pub enum LikeOperator {
697 Glob,
699 Like,
701 Match,
703 Regexp,
705}
706
707impl LikeOperator {
708 pub fn from_token(token_type: YYCODETYPE, token: Token) -> Self {
710 if token_type == TK_MATCH as YYCODETYPE {
711 return Self::Match;
712 } else if token_type == TK_LIKE_KW as YYCODETYPE {
713 let token = token.1;
714 if b"LIKE".eq_ignore_ascii_case(token) {
715 return Self::Like;
716 } else if b"GLOB".eq_ignore_ascii_case(token) {
717 return Self::Glob;
718 } else if b"REGEXP".eq_ignore_ascii_case(token) {
719 return Self::Regexp;
720 }
721 }
722 unreachable!()
723 }
724}
725
726#[derive(Copy, Clone, Debug, PartialEq, Eq)]
728#[cfg_attr(feature = "serde", derive(Serialize))]
729pub enum Operator {
730 Add,
732 And,
734 ArrowRight,
736 ArrowRightShift,
738 BitwiseAnd,
740 BitwiseOr,
742 Concat,
744 Equals,
746 Divide,
748 Greater,
750 GreaterEquals,
752 Is,
754 IsNot,
756 LeftShift,
758 Less,
760 LessEquals,
762 Modulus,
764 Multiply,
766 NotEquals,
768 Or,
770 RightShift,
772 Subtract,
774}
775
776impl From<YYCODETYPE> for Operator {
777 fn from(token_type: YYCODETYPE) -> Self {
778 match token_type {
779 x if x == TK_AND as YYCODETYPE => Self::And,
780 x if x == TK_OR as YYCODETYPE => Self::Or,
781 x if x == TK_LT as YYCODETYPE => Self::Less,
782 x if x == TK_GT as YYCODETYPE => Self::Greater,
783 x if x == TK_GE as YYCODETYPE => Self::GreaterEquals,
784 x if x == TK_LE as YYCODETYPE => Self::LessEquals,
785 x if x == TK_EQ as YYCODETYPE => Self::Equals,
786 x if x == TK_NE as YYCODETYPE => Self::NotEquals,
787 x if x == TK_BITAND as YYCODETYPE => Self::BitwiseAnd,
788 x if x == TK_BITOR as YYCODETYPE => Self::BitwiseOr,
789 x if x == TK_LSHIFT as YYCODETYPE => Self::LeftShift,
790 x if x == TK_RSHIFT as YYCODETYPE => Self::RightShift,
791 x if x == TK_PLUS as YYCODETYPE => Self::Add,
792 x if x == TK_MINUS as YYCODETYPE => Self::Subtract,
793 x if x == TK_STAR as YYCODETYPE => Self::Multiply,
794 x if x == TK_SLASH as YYCODETYPE => Self::Divide,
795 x if x == TK_REM as YYCODETYPE => Self::Modulus,
796 x if x == TK_CONCAT as YYCODETYPE => Self::Concat,
797 x if x == TK_IS as YYCODETYPE => Self::Is,
798 x if x == TK_NOT as YYCODETYPE => Self::IsNot,
799 _ => unreachable!(),
800 }
801 }
802}
803
804#[derive(Copy, Clone, Debug, PartialEq, Eq)]
806#[cfg_attr(feature = "serde", derive(Serialize))]
807pub enum UnaryOperator {
808 BitwiseNot,
810 Negative,
812 Not,
814 Positive,
816}
817
818impl From<YYCODETYPE> for UnaryOperator {
819 fn from(token_type: YYCODETYPE) -> Self {
820 match token_type {
821 x if x == TK_BITNOT as YYCODETYPE => Self::BitwiseNot,
822 x if x == TK_MINUS as YYCODETYPE => Self::Negative,
823 x if x == TK_NOT as YYCODETYPE => Self::Not,
824 x if x == TK_PLUS as YYCODETYPE => Self::Positive,
825 _ => unreachable!(),
826 }
827 }
828}
829
830#[derive(Debug, PartialEq, Eq)]
834#[cfg_attr(feature = "serde", derive(Serialize))]
835pub struct Select<'bump> {
836 pub with: Option<With<'bump>>, pub body: SelectBody<'bump>,
840 pub order_by: Option<&'bump [SortedColumn<'bump>]>, pub limit: Option<&'bump Limit<'bump>>,
844}
845
846impl<'bump> Select<'bump> {
847 pub fn new(
849 with: Option<With<'bump>>,
850 body: SelectBody<'bump>,
851 order_by: Option<Vec<'bump, SortedColumn<'bump>>>,
852 limit: Option<&'bump Limit<'bump>>,
853 ) -> Result<Self, ParserError> {
854 let select = Self {
855 with,
856 body,
857 order_by: order_by.map(|ob| ob.into_bump_slice()),
858 limit,
859 };
860 #[cfg(feature = "extra_checks")]
861 if let Self {
862 order_by: Some(scs),
863 ..
864 } = select
865 {
866 if let ColumnCount::Fixed(n) = select.column_count() {
867 for sc in scs {
868 sc.expr.check_range("ORDER", n)?;
869 }
870 }
871 }
872 Ok(select)
873 }
874}
875
876#[derive(Debug, PartialEq, Eq)]
878#[cfg_attr(feature = "serde", derive(Serialize))]
879pub struct SelectBody<'bump> {
880 pub select: OneSelect<'bump>,
882 pub compounds: Option<Vec<'bump, CompoundSelect<'bump>>>,
884}
885
886impl<'bump> SelectBody<'bump> {
887 pub(crate) fn push(
888 &mut self,
889 cs: CompoundSelect<'bump>,
890 b: &'bump Bump,
891 ) -> Result<(), ParserError> {
892 #[cfg(feature = "extra_checks")]
893 if let ColumnCount::Fixed(n) = self.select.column_count() {
894 if let ColumnCount::Fixed(m) = cs.select.column_count() {
895 if n != m {
896 return Err(custom_err!(
897 "SELECTs to the left and right of {} do not have the same number of result columns",
898 cs.operator
899 ));
900 }
901 }
902 }
903 if let Some(ref mut v) = self.compounds {
904 v.push(cs);
905 } else {
906 self.compounds = Some(bumpalo::vec![in b; cs]);
907 }
908 Ok(())
909 }
910}
911
912#[derive(Debug, PartialEq, Eq)]
914#[cfg_attr(feature = "serde", derive(Serialize))]
915pub struct CompoundSelect<'bump> {
916 pub operator: CompoundOperator,
918 pub select: OneSelect<'bump>,
920}
921
922#[derive(Copy, Clone, Debug, PartialEq, Eq)]
925#[cfg_attr(feature = "serde", derive(Serialize))]
926pub enum CompoundOperator {
927 Union,
929 UnionAll,
931 Except,
933 Intersect,
935}
936
937#[derive(Debug, PartialEq, Eq)]
940#[cfg_attr(feature = "serde", derive(Serialize))]
941pub enum OneSelect<'bump> {
942 Select {
944 distinctness: Option<Distinctness>,
946 columns: &'bump [ResultColumn<'bump>],
948 from: Option<FromClause<'bump>>,
950 where_clause: Option<&'bump Expr<'bump>>,
952 group_by: Option<&'bump [Expr<'bump>]>,
954 having: Option<&'bump Expr<'bump>>, window_clause: Option<&'bump [WindowDef<'bump>]>,
958 },
959 Values(Vec<'bump, Vec<'bump, Expr<'bump>>>),
961}
962
963impl<'bump> OneSelect<'bump> {
964 #[expect(clippy::too_many_arguments)]
966 pub fn new(
967 distinctness: Option<Distinctness>,
968 columns: Vec<'bump, ResultColumn<'bump>>,
969 from: Option<FromClause<'bump>>,
970 where_clause: Option<Expr<'bump>>,
971 group_by: Option<Vec<'bump, Expr<'bump>>>,
972 having: Option<Expr<'bump>>,
973 window_clause: Option<Vec<'bump, WindowDef<'bump>>>,
974 b: &'bump Bump,
975 ) -> Result<Self, ParserError> {
976 #[cfg(feature = "extra_checks")]
977 if from.is_none()
978 && columns
979 .iter()
980 .any(|rc| matches!(rc, ResultColumn::Star | ResultColumn::TableStar(_)))
981 {
982 return Err(custom_err!("no tables specified"));
983 }
984 let select = Self::Select {
985 distinctness,
986 columns: columns.into_bump_slice(),
987 from,
988 where_clause: where_clause.map(|wc| b.alloc(wc) as _),
989 group_by: group_by.map(|gb| gb.into_bump_slice()),
990 having: having.map(|h| b.alloc(h) as _),
991 window_clause: window_clause.map(|wc| wc.into_bump_slice()),
992 };
993 #[cfg(feature = "extra_checks")]
994 if let Self::Select {
995 group_by: Some(gb), ..
996 } = select
997 {
998 if let ColumnCount::Fixed(n) = select.column_count() {
999 for expr in gb {
1000 expr.check_range("GROUP", n)?;
1001 }
1002 }
1003 }
1004 Ok(select)
1005 }
1006 pub fn push(
1008 values: &mut Vec<'bump, Vec<'bump, Expr<'bump>>>,
1009 v: Vec<'bump, Expr<'bump>>,
1010 ) -> Result<(), ParserError> {
1011 #[cfg(feature = "extra_checks")]
1012 if values[0].len() != v.len() {
1013 return Err(custom_err!("all VALUES must have the same number of terms"));
1014 }
1015 values.push(v);
1016 Ok(())
1017 }
1018}
1019
1020#[derive(Debug, PartialEq, Eq)]
1023#[cfg_attr(feature = "serde", derive(Serialize))]
1024pub struct FromClause<'bump> {
1025 pub select: Option<&'bump SelectTable<'bump>>, pub joins: Option<Vec<'bump, JoinedSelectTable<'bump>>>,
1029 op: Option<JoinOperator>, }
1031impl<'bump> FromClause<'bump> {
1032 pub(crate) fn empty() -> Self {
1033 Self {
1034 select: None,
1035 joins: None,
1036 op: None,
1037 }
1038 }
1039
1040 pub(crate) fn push(
1041 &mut self,
1042 table: SelectTable<'bump>,
1043 jc: Option<JoinConstraint<'bump>>,
1044 b: &'bump Bump,
1045 ) -> Result<(), ParserError> {
1046 let op = self.op.take();
1047 if let Some(op) = op {
1048 let jst = JoinedSelectTable {
1049 operator: op,
1050 table,
1051 constraint: jc,
1052 };
1053 if jst.operator.is_natural() && jst.constraint.is_some() {
1054 return Err(custom_err!(
1055 "a NATURAL join may not have an ON or USING clause"
1056 ));
1057 }
1058 if let Some(ref mut joins) = self.joins {
1059 joins.push(jst);
1060 } else {
1061 self.joins = Some(bumpalo::vec![in b; jst]);
1062 }
1063 } else {
1064 if jc.is_some() {
1065 return Err(custom_err!("a JOIN clause is required before ON"));
1066 }
1067 debug_assert!(self.select.is_none());
1068 debug_assert!(self.joins.is_none());
1069 self.select = Some(b.alloc(table));
1070 }
1071 Ok(())
1072 }
1073
1074 pub(crate) fn push_op(&mut self, op: JoinOperator) {
1075 self.op = Some(op);
1076 }
1077}
1078
1079#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1081#[cfg_attr(feature = "serde", derive(Serialize))]
1082pub enum Distinctness {
1083 Distinct,
1085 All,
1087}
1088
1089#[derive(Debug, PartialEq, Eq)]
1092#[cfg_attr(feature = "serde", derive(Serialize))]
1093pub enum ResultColumn<'bump> {
1094 Expr(Expr<'bump>, Option<As<'bump>>),
1096 Star,
1098 TableStar(Name<'bump>),
1100}
1101
1102#[derive(Debug, PartialEq, Eq)]
1104#[cfg_attr(feature = "serde", derive(Serialize))]
1105pub enum As<'bump> {
1106 As(Name<'bump>),
1108 Elided(Name<'bump>), }
1111
1112#[derive(Debug, PartialEq, Eq)]
1115#[cfg_attr(feature = "serde", derive(Serialize))]
1116pub struct JoinedSelectTable<'bump> {
1117 pub operator: JoinOperator,
1119 pub table: SelectTable<'bump>,
1121 pub constraint: Option<JoinConstraint<'bump>>,
1123}
1124
1125#[derive(Debug, PartialEq, Eq)]
1128#[cfg_attr(feature = "serde", derive(Serialize))]
1129pub enum SelectTable<'bump> {
1130 Table(
1132 QualifiedName<'bump>,
1133 Option<As<'bump>>,
1134 Option<Indexed<'bump>>,
1135 ),
1136 TableCall(
1138 QualifiedName<'bump>,
1139 Option<&'bump [Expr<'bump>]>,
1140 Option<As<'bump>>,
1141 ),
1142 Select(&'bump Select<'bump>, Option<As<'bump>>),
1144 Sub(FromClause<'bump>, Option<As<'bump>>),
1146}
1147
1148#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1151#[cfg_attr(feature = "serde", derive(Serialize))]
1152pub enum JoinOperator {
1153 Comma,
1155 TypedJoin(Option<JoinType>),
1157}
1158
1159impl JoinOperator {
1160 pub(crate) fn from(
1161 token: Token,
1162 n1: Option<Name>,
1163 n2: Option<Name>,
1164 ) -> Result<Self, ParserError> {
1165 Ok({
1166 let mut jt = JoinType::try_from(token.1)?;
1167 for n in [&n1, &n2].into_iter().flatten() {
1168 jt |= JoinType::try_from(n.0.as_bytes())?;
1169 }
1170 if (jt & (JoinType::INNER | JoinType::OUTER)) == (JoinType::INNER | JoinType::OUTER)
1171 || (jt & (JoinType::OUTER | JoinType::LEFT | JoinType::RIGHT)) == JoinType::OUTER
1172 {
1173 return Err(custom_err!(
1174 "unknown join type: {} {} {}",
1175 str::from_utf8(token.1).unwrap_or("invalid utf8"),
1176 n1.as_ref().map_or("", |n| n.0),
1177 n2.as_ref().map_or("", |n| n.0)
1178 ));
1179 }
1180 Self::TypedJoin(Some(jt))
1181 })
1182 }
1183 fn is_natural(&self) -> bool {
1184 match self {
1185 Self::TypedJoin(Some(jt)) => jt.contains(JoinType::NATURAL),
1186 _ => false,
1187 }
1188 }
1189}
1190
1191bitflags::bitflags! {
1193 #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1195 #[cfg_attr(feature = "serde", derive(Serialize))]
1196 pub struct JoinType: u8 {
1197 const INNER = 0x01;
1199 const CROSS = 0x02;
1201 const NATURAL = 0x04;
1203 const LEFT = 0x08;
1205 const RIGHT = 0x10;
1207 const OUTER = 0x20;
1209 }
1210}
1211
1212impl TryFrom<&[u8]> for JoinType {
1213 type Error = ParserError;
1214 fn try_from(s: &[u8]) -> Result<Self, ParserError> {
1215 if b"CROSS".eq_ignore_ascii_case(s) {
1216 Ok(Self::INNER | Self::CROSS)
1217 } else if b"FULL".eq_ignore_ascii_case(s) {
1218 Ok(Self::LEFT | Self::RIGHT | Self::OUTER)
1219 } else if b"INNER".eq_ignore_ascii_case(s) {
1220 Ok(Self::INNER)
1221 } else if b"LEFT".eq_ignore_ascii_case(s) {
1222 Ok(Self::LEFT | Self::OUTER)
1223 } else if b"NATURAL".eq_ignore_ascii_case(s) {
1224 Ok(Self::NATURAL)
1225 } else if b"RIGHT".eq_ignore_ascii_case(s) {
1226 Ok(Self::RIGHT | Self::OUTER)
1227 } else if b"OUTER".eq_ignore_ascii_case(s) {
1228 Ok(Self::OUTER)
1229 } else {
1230 Err(custom_err!(
1231 "unknown join type: {}",
1232 str::from_utf8(s).unwrap_or("invalid utf8")
1233 ))
1234 }
1235 }
1236}
1237
1238#[derive(Debug, PartialEq, Eq)]
1240#[cfg_attr(feature = "serde", derive(Serialize))]
1241pub enum JoinConstraint<'bump> {
1242 On(Expr<'bump>),
1244 Using(DistinctNames<'bump>),
1246}
1247
1248#[derive(Clone, Debug, PartialEq, Eq)]
1250#[cfg_attr(feature = "serde", derive(Serialize))]
1251pub struct Id<'bump>(pub &'bump str);
1252
1253impl<'bump> Id<'bump> {
1254 pub fn from_token(ty: YYCODETYPE, token: Token, b: &'bump Bump) -> Self {
1256 Self(from_token(ty, token, b))
1257 }
1258}
1259
1260#[derive(Clone, Debug, Eq)]
1264#[cfg_attr(feature = "serde", derive(Serialize))]
1265pub struct Name<'bump>(pub &'bump str); pub(crate) fn unquote(s: &str) -> (&str, u8) {
1268 if s.is_empty() {
1269 return (s, 0);
1270 }
1271 let bytes = s.as_bytes();
1272 let mut quote = bytes[0];
1273 if quote != b'"' && quote != b'`' && quote != b'\'' && quote != b'[' {
1274 return (s, 0);
1275 } else if quote == b'[' {
1276 quote = b']';
1277 }
1278 debug_assert!(bytes.len() > 1);
1279 debug_assert_eq!(quote, bytes[bytes.len() - 1]);
1280 let sub = &s[1..bytes.len() - 1];
1281 if quote == b']' || sub.len() < 2 {
1282 (sub, 0)
1283 } else {
1284 (sub, quote)
1285 }
1286}
1287
1288impl<'bump> Name<'bump> {
1289 pub fn from_token(ty: YYCODETYPE, token: Token, b: &'bump Bump) -> Self {
1291 Self(from_token(ty, token, b))
1292 }
1293
1294 fn as_bytes(&self) -> QuotedIterator<'_> {
1295 let (sub, quote) = unquote(self.0);
1296 QuotedIterator(sub.bytes(), quote)
1297 }
1298 #[cfg(feature = "extra_checks")]
1299 fn is_reserved(&self) -> bool {
1300 let bytes = self.as_bytes();
1301 let reserved = QuotedIterator("sqlite_".bytes(), 0);
1302 bytes.zip(reserved).fold(0u8, |acc, (b1, b2)| {
1303 acc + if b1.eq_ignore_ascii_case(&b2) { 1 } else { 0 }
1304 }) == 7u8
1305 }
1306}
1307
1308struct QuotedIterator<'s>(Bytes<'s>, u8);
1309impl Iterator for QuotedIterator<'_> {
1310 type Item = u8;
1311
1312 fn next(&mut self) -> Option<u8> {
1313 match self.0.next() {
1314 x @ Some(b) => {
1315 if b == self.1 && self.0.next() != Some(self.1) {
1316 panic!("Malformed string literal: {:?}", self.0);
1317 }
1318 x
1319 }
1320 x => x,
1321 }
1322 }
1323
1324 fn size_hint(&self) -> (usize, Option<usize>) {
1325 if self.1 == 0 {
1326 return self.0.size_hint();
1327 }
1328 (0, None)
1329 }
1330}
1331
1332fn eq_ignore_case_and_quote(mut it: QuotedIterator<'_>, mut other: QuotedIterator<'_>) -> bool {
1333 loop {
1334 match (it.next(), other.next()) {
1335 (Some(b1), Some(b2)) => {
1336 if !b1.eq_ignore_ascii_case(&b2) {
1337 return false;
1338 }
1339 }
1340 (None, None) => break,
1341 _ => return false,
1342 }
1343 }
1344 true
1345}
1346
1347impl<'bump> std::hash::Hash for Name<'bump> {
1349 fn hash<H: std::hash::Hasher>(&self, hasher: &mut H) {
1350 self.as_bytes()
1351 .for_each(|b| hasher.write_u8(b.to_ascii_lowercase()));
1352 }
1353}
1354impl<'bump> PartialEq for Name<'bump> {
1356 fn eq(&self, other: &Self) -> bool {
1357 eq_ignore_case_and_quote(self.as_bytes(), other.as_bytes())
1358 }
1359}
1360impl<'bump> PartialEq<str> for Name<'bump> {
1362 fn eq(&self, other: &str) -> bool {
1363 eq_ignore_case_and_quote(self.as_bytes(), QuotedIterator(other.bytes(), 0u8))
1364 }
1365}
1366impl<'bump> PartialEq<&str> for Name<'bump> {
1368 fn eq(&self, other: &&str) -> bool {
1369 eq_ignore_case_and_quote(self.as_bytes(), QuotedIterator(other.bytes(), 0u8))
1370 }
1371}
1372
1373#[derive(Debug, PartialEq, Eq)]
1375#[cfg_attr(feature = "serde", derive(Serialize))]
1376pub struct QualifiedName<'bump> {
1377 pub db_name: Option<Name<'bump>>,
1379 pub name: Name<'bump>,
1381 pub alias: Option<Name<'bump>>, }
1384
1385impl<'bump> QualifiedName<'bump> {
1386 pub fn single(name: Name<'bump>) -> Self {
1388 Self {
1389 db_name: None,
1390 name,
1391 alias: None,
1392 }
1393 }
1394 pub fn fullname(db_name: Name<'bump>, name: Name<'bump>) -> Self {
1396 Self {
1397 db_name: Some(db_name),
1398 name,
1399 alias: None,
1400 }
1401 }
1402 pub fn xfullname(db_name: Name<'bump>, name: Name<'bump>, alias: Name<'bump>) -> Self {
1404 Self {
1405 db_name: Some(db_name),
1406 name,
1407 alias: Some(alias),
1408 }
1409 }
1410 pub fn alias(name: Name<'bump>, alias: Name<'bump>) -> Self {
1412 Self {
1413 db_name: None,
1414 name,
1415 alias: Some(alias),
1416 }
1417 }
1418}
1419
1420#[derive(Debug, PartialEq, Eq)]
1422#[cfg_attr(feature = "serde", derive(Serialize))]
1423pub struct DistinctNames<'bump>(Vec<'bump, Name<'bump>>);
1424
1425impl<'bump> DistinctNames<'bump> {
1426 pub fn new(name: Name<'bump>, bump: &'bump Bump) -> Self {
1428 let mut dn = Self(Vec::new_in(bump));
1429 dn.0.push(name);
1430 dn
1431 }
1432 pub fn single(name: Name<'bump>, bump: &'bump Bump) -> Self {
1434 let mut dn = Self(Vec::with_capacity_in(1, bump));
1435 dn.0.push(name);
1436 dn
1437 }
1438 pub fn insert(&mut self, name: Name<'bump>) -> Result<(), ParserError> {
1440 if self.0.contains(&name) {
1441 return Err(custom_err!("column \"{}\" specified more than once", name));
1442 }
1443 self.0.push(name);
1444 Ok(())
1445 }
1446}
1447impl<'bump> Deref for DistinctNames<'bump> {
1448 type Target = Vec<'bump, Name<'bump>>;
1449
1450 fn deref(&self) -> &Vec<'bump, Name<'bump>> {
1451 &self.0
1452 }
1453}
1454
1455#[derive(Debug, PartialEq, Eq)]
1458#[cfg_attr(feature = "serde", derive(Serialize))]
1459pub enum AlterTableBody<'bump> {
1460 RenameTo(Name<'bump>),
1462 AddColumn(ColumnDefinition<'bump>), DropColumnNotNull(Name<'bump>), SetColumnNotNull(Name<'bump>, Option<ResolveType>), RenameColumn {
1470 old: Name<'bump>,
1472 new: Name<'bump>,
1474 },
1475 DropColumn(Name<'bump>), AddConstraint(NamedTableConstraint<'bump>), DropConstraint(Name<'bump>),
1481}
1482
1483bitflags::bitflags! {
1484 #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1486 #[cfg_attr(feature = "serde", derive(Serialize))]
1487 pub struct TabFlags: u32 {
1488 const HasHidden = 0x00000002;
1491 const HasPrimaryKey = 0x00000004;
1493 const Autoincrement = 0x00000008;
1495 const HasVirtual = 0x00000020;
1498 const HasStored = 0x00000040;
1500 const HasGenerated = 0x00000060;
1502 const WithoutRowid = 0x00000080;
1504 const HasNotNull = 0x00000800;
1511 const Strict = 0x00010000;
1517 }
1518}
1519
1520#[derive(Debug, PartialEq, Eq)]
1524#[cfg_attr(feature = "serde", derive(Serialize))]
1525pub enum CreateTableBody<'bump> {
1526 ColumnsAndConstraints {
1528 columns: Vec<'bump, ColumnDefinition<'bump>>,
1530 constraints: Option<&'bump [NamedTableConstraint<'bump>]>,
1532 flags: TabFlags,
1534 },
1535 AsSelect(&'bump Select<'bump>),
1537}
1538
1539impl<'bump> CreateTableBody<'bump> {
1540 pub fn columns_and_constraints(
1542 columns: Vec<'bump, ColumnDefinition<'bump>>,
1543 constraints: Option<Vec<'bump, NamedTableConstraint<'bump>>>,
1544 mut flags: TabFlags,
1545 ) -> Result<Self, ParserError> {
1546 for col in &columns {
1547 if col.flags.contains(ColFlags::PRIMKEY) {
1548 flags |= TabFlags::HasPrimaryKey;
1549 }
1550 }
1551 if let Some(ref constraints) = constraints {
1552 for c in constraints {
1553 if let NamedTableConstraint {
1554 constraint: TableConstraint::PrimaryKey { .. },
1555 ..
1556 } = c
1557 {
1558 if flags.contains(TabFlags::HasPrimaryKey) {
1559 #[cfg(feature = "extra_checks")]
1561 return Err(custom_err!("table has more than one primary key"));
1562 } else {
1563 flags |= TabFlags::HasPrimaryKey;
1564 }
1565 }
1566 }
1567 }
1568 Ok(Self::ColumnsAndConstraints {
1569 columns,
1570 constraints: constraints.map(|cs| cs.into_bump_slice()),
1571 flags,
1572 })
1573 }
1574}
1575
1576bitflags::bitflags! {
1577 #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1579 #[cfg_attr(feature = "serde", derive(Serialize))]
1580 pub struct ColFlags: u16 {
1581 const PRIMKEY = 0x0001;
1583 const HASTYPE = 0x0004;
1587 const UNIQUE = 0x0008;
1589 const VIRTUAL = 0x0020;
1592 const STORED = 0x0040;
1594 const HASCOLL = 0x0200;
1598 const GENERATED = Self::STORED.bits() | Self::VIRTUAL.bits();
1601 }
1604}
1605
1606#[derive(Debug, PartialEq, Eq)]
1609#[cfg_attr(feature = "serde", derive(Serialize))]
1610pub struct ColumnDefinition<'bump> {
1611 pub col_name: Name<'bump>,
1613 pub col_type: Option<Type<'bump>>,
1615 pub constraints: &'bump [NamedColumnConstraint<'bump>],
1617 pub flags: ColFlags,
1619}
1620
1621impl<'bump> ColumnDefinition<'bump> {
1622 pub fn new(
1624 col_name: Name<'bump>,
1625 mut col_type: Option<Type<'bump>>,
1626 constraints: Vec<'bump, NamedColumnConstraint<'bump>>,
1627 b: &'bump Bump,
1628 ) -> Result<Self, ParserError> {
1629 let mut flags = ColFlags::empty();
1630 #[allow(unused_variables)]
1631 let mut default = false;
1632 for constraint in &constraints {
1633 match &constraint.constraint {
1634 #[allow(unused_assignments)]
1635 ColumnConstraint::Default(..) => {
1636 default = true;
1637 }
1638 ColumnConstraint::Collate { .. } => {
1639 flags |= ColFlags::HASCOLL;
1640 }
1641 ColumnConstraint::Generated { typ, .. } => {
1642 flags |= ColFlags::VIRTUAL;
1643 if let Some(id) = typ {
1644 if id.0.eq_ignore_ascii_case("STORED") {
1645 flags |= ColFlags::STORED;
1646 }
1647 }
1648 }
1649 #[cfg(feature = "extra_checks")]
1650 ColumnConstraint::ForeignKey {
1651 clause:
1652 ForeignKeyClause {
1653 tbl_name, columns, ..
1654 },
1655 ..
1656 } => {
1657 if columns.as_ref().map_or(0, |cs| cs.len()) > 1 {
1659 return Err(custom_err!(
1660 "foreign key on {} should reference only one column of table {}",
1661 col_name,
1662 tbl_name
1663 ));
1664 }
1665 }
1666 #[allow(unused_variables)]
1667 ColumnConstraint::PrimaryKey { auto_increment, .. } => {
1668 #[cfg(feature = "extra_checks")]
1669 if *auto_increment
1670 && col_type
1671 .as_ref()
1672 .is_none_or(|t| !unquote(t.name).0.eq_ignore_ascii_case("INTEGER"))
1673 {
1674 return Err(custom_err!(
1675 "AUTOINCREMENT is only allowed on an INTEGER PRIMARY KEY"
1676 ));
1677 }
1678 flags |= ColFlags::PRIMKEY | ColFlags::UNIQUE;
1679 }
1680 ColumnConstraint::Unique(..) => {
1681 flags |= ColFlags::UNIQUE;
1682 }
1683 _ => {}
1684 }
1685 }
1686 #[cfg(feature = "extra_checks")]
1687 if flags.contains(ColFlags::PRIMKEY) && flags.intersects(ColFlags::GENERATED) {
1688 return Err(custom_err!(
1689 "generated columns cannot be part of the PRIMARY KEY"
1690 ));
1691 } else if default && flags.intersects(ColFlags::GENERATED) {
1692 return Err(custom_err!("cannot use DEFAULT on a generated column"));
1693 }
1694 if flags.intersects(ColFlags::GENERATED) {
1695 if let Some(ref mut col_type) = col_type {
1697 let mut split = col_type.name.split_ascii_whitespace();
1698 if split
1699 .next_back()
1700 .is_some_and(|s| s.eq_ignore_ascii_case("ALWAYS"))
1701 && split
1702 .next_back()
1703 .is_some_and(|s| s.eq_ignore_ascii_case("GENERATED"))
1704 {
1705 let mut new_type = bumpalo::collections::String::new_in(b);
1707 for (i, item) in split.enumerate() {
1708 if i > 0 {
1709 new_type.push(' ');
1710 }
1711 new_type.push_str(item);
1712 }
1713 col_type.name = new_type.into_bump_str();
1714 }
1715 }
1716 if col_type.as_ref().is_some_and(|ct| ct.name.is_empty()) {
1717 col_type = None;
1718 }
1719 }
1720 if col_type.as_ref().is_some_and(|t| !t.name.is_empty()) {
1721 flags |= ColFlags::HASTYPE;
1722 }
1723 Ok(Self {
1724 col_name,
1725 col_type,
1726 constraints: constraints.into_bump_slice(),
1727 flags,
1728 })
1729 }
1730 pub fn add_column(columns: &mut Vec<'bump, Self>, cd: Self) -> Result<(), ParserError> {
1732 if columns.iter().any(|c| c.col_name == cd.col_name) {
1733 return Err(custom_err!("duplicate column name: {}", cd.col_name));
1734 } else if cd.flags.contains(ColFlags::PRIMKEY)
1735 && columns.iter().any(|c| c.flags.contains(ColFlags::PRIMKEY))
1736 {
1737 #[cfg(feature = "extra_checks")]
1738 return Err(custom_err!("table has more than one primary key")); }
1740 columns.push(cd);
1741 Ok(())
1742 }
1743}
1744
1745#[derive(Debug, PartialEq, Eq)]
1748#[cfg_attr(feature = "serde", derive(Serialize))]
1749pub struct NamedColumnConstraint<'bump> {
1750 pub name: Option<Name<'bump>>,
1752 pub constraint: ColumnConstraint<'bump>,
1754}
1755
1756#[derive(Debug, PartialEq, Eq)]
1759#[cfg_attr(feature = "serde", derive(Serialize))]
1760pub enum ColumnConstraint<'bump> {
1761 PrimaryKey {
1763 order: Option<SortOrder>,
1765 conflict_clause: Option<ResolveType>,
1767 auto_increment: bool,
1769 },
1770 NotNull {
1772 nullable: bool,
1774 conflict_clause: Option<ResolveType>,
1776 },
1777 Unique(Option<ResolveType>),
1779 Check(Expr<'bump>),
1781 Default(Expr<'bump>),
1783 Defer(DeferSubclause), Collate {
1787 collation_name: Name<'bump>, },
1790 ForeignKey {
1792 clause: ForeignKeyClause<'bump>,
1794 defer_clause: Option<DeferSubclause>,
1796 },
1797 Generated {
1799 expr: Expr<'bump>,
1801 typ: Option<Id<'bump>>,
1803 },
1804}
1805
1806#[derive(Debug, PartialEq, Eq)]
1809#[cfg_attr(feature = "serde", derive(Serialize))]
1810pub struct NamedTableConstraint<'bump> {
1811 pub name: Option<Name<'bump>>,
1813 pub constraint: TableConstraint<'bump>,
1815}
1816
1817#[derive(Debug, PartialEq, Eq)]
1820#[cfg_attr(feature = "serde", derive(Serialize))]
1821pub enum TableConstraint<'bump> {
1822 PrimaryKey {
1824 columns: &'bump [SortedColumn<'bump>],
1826 auto_increment: bool,
1828 conflict_clause: Option<ResolveType>,
1830 },
1831 Unique {
1833 columns: &'bump [SortedColumn<'bump>],
1835 conflict_clause: Option<ResolveType>,
1837 },
1838 Check(Expr<'bump>, Option<ResolveType>),
1840 ForeignKey {
1842 columns: &'bump [IndexedColumn<'bump>],
1844 clause: ForeignKeyClause<'bump>,
1846 defer_clause: Option<DeferSubclause>,
1848 },
1849}
1850
1851impl<'bump> TableConstraint<'bump> {
1852 pub fn primary_key(
1854 columns: Vec<'bump, SortedColumn<'bump>>,
1855 auto_increment: bool,
1856 conflict_clause: Option<ResolveType>,
1857 ) -> Result<Self, ParserError> {
1858 has_expression(&columns)?;
1859 has_explicit_nulls(&columns)?;
1860 Ok(Self::PrimaryKey {
1861 columns: columns.into_bump_slice(),
1862 auto_increment,
1863 conflict_clause,
1864 })
1865 }
1866 pub fn unique(
1868 columns: Vec<'bump, SortedColumn<'bump>>,
1869 conflict_clause: Option<ResolveType>,
1870 ) -> Result<Self, ParserError> {
1871 has_expression(&columns)?;
1872 has_explicit_nulls(&columns)?;
1873 Ok(Self::Unique {
1874 columns: columns.into_bump_slice(),
1875 conflict_clause,
1876 })
1877 }
1878}
1879
1880#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1882#[cfg_attr(feature = "serde", derive(Serialize))]
1883pub enum SortOrder {
1884 Asc,
1886 Desc,
1888}
1889
1890#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1892#[cfg_attr(feature = "serde", derive(Serialize))]
1893pub enum NullsOrder {
1894 First,
1896 Last,
1898}
1899
1900#[derive(Debug, PartialEq, Eq)]
1903#[cfg_attr(feature = "serde", derive(Serialize))]
1904pub struct ForeignKeyClause<'bump> {
1905 pub tbl_name: Name<'bump>,
1907 pub columns: Option<&'bump [IndexedColumn<'bump>]>,
1909 pub args: &'bump [RefArg<'bump>],
1911}
1912
1913impl<'bump> ForeignKeyClause<'bump> {
1914 pub fn new(
1916 tbl_name: Name<'bump>,
1917 columns: Option<Vec<'bump, IndexedColumn<'bump>>>,
1918 args: Vec<'bump, RefArg<'bump>>,
1919 ) -> Self {
1920 ForeignKeyClause {
1921 tbl_name,
1922 columns: columns.map(|cs| cs.into_bump_slice()),
1923 args: args.into_bump_slice(),
1924 }
1925 }
1926}
1927
1928#[derive(Debug, PartialEq, Eq)]
1930#[cfg_attr(feature = "serde", derive(Serialize))]
1931pub enum RefArg<'bump> {
1932 OnDelete(RefAct),
1934 OnInsert(RefAct),
1936 OnUpdate(RefAct),
1938 Match(Name<'bump>),
1940}
1941
1942#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1944#[cfg_attr(feature = "serde", derive(Serialize))]
1945pub enum RefAct {
1946 SetNull,
1948 SetDefault,
1950 Cascade,
1952 Restrict,
1954 NoAction,
1956}
1957
1958#[derive(Clone, Debug, PartialEq, Eq)]
1960#[cfg_attr(feature = "serde", derive(Serialize))]
1961pub struct DeferSubclause {
1962 pub deferrable: bool,
1964 pub init_deferred: Option<InitDeferredPred>,
1966}
1967
1968#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1970#[cfg_attr(feature = "serde", derive(Serialize))]
1971pub enum InitDeferredPred {
1972 InitiallyDeferred,
1974 InitiallyImmediate, }
1977
1978#[derive(Debug, PartialEq, Eq)]
1981#[cfg_attr(feature = "serde", derive(Serialize))]
1982pub struct IndexedColumn<'bump> {
1983 pub col_name: Name<'bump>,
1985 pub collation_name: Option<Name<'bump>>, pub order: Option<SortOrder>,
1989}
1990
1991#[derive(Debug, PartialEq, Eq)]
1993#[cfg_attr(feature = "serde", derive(Serialize))]
1994pub enum Indexed<'bump> {
1995 IndexedBy(Name<'bump>),
1997 NotIndexed,
1999}
2000
2001#[derive(Debug, PartialEq, Eq)]
2003#[cfg_attr(feature = "serde", derive(Serialize))]
2004pub struct SortedColumn<'bump> {
2005 pub expr: Expr<'bump>,
2007 pub order: Option<SortOrder>,
2009 pub nulls: Option<NullsOrder>,
2011}
2012
2013fn has_expression(columns: &Vec<SortedColumn>) -> Result<(), ParserError> {
2014 for _column in columns {
2015 if false {
2016 return Err(custom_err!(
2017 "expressions prohibited in PRIMARY KEY and UNIQUE constraints"
2018 ));
2019 }
2020 }
2021 Ok(())
2022}
2023#[allow(unused_variables)]
2024fn has_explicit_nulls(columns: &[SortedColumn]) -> Result<(), ParserError> {
2025 #[cfg(feature = "extra_checks")]
2026 for column in columns {
2027 if let Some(ref nulls) = column.nulls {
2028 return Err(custom_err!(
2029 "unsupported use of NULLS {}",
2030 if *nulls == NullsOrder::First {
2031 "FIRST"
2032 } else {
2033 "LAST"
2034 }
2035 ));
2036 }
2037 }
2038 Ok(())
2039}
2040
2041#[derive(Debug, PartialEq, Eq)]
2043#[cfg_attr(feature = "serde", derive(Serialize))]
2044pub struct Limit<'bump> {
2045 pub expr: Expr<'bump>,
2047 pub offset: Option<Expr<'bump>>, }
2050
2051#[derive(Debug, PartialEq, Eq)]
2055#[cfg_attr(feature = "serde", derive(Serialize))]
2056pub enum InsertBody<'bump> {
2057 Select(&'bump Select<'bump>, Option<&'bump Upsert<'bump>>),
2059 DefaultValues,
2061}
2062
2063#[derive(Debug, PartialEq, Eq)]
2065#[cfg_attr(feature = "serde", derive(Serialize))]
2066pub struct Set<'bump> {
2067 pub col_names: DistinctNames<'bump>,
2069 pub expr: Expr<'bump>,
2071}
2072
2073#[derive(Debug, PartialEq, Eq)]
2076#[cfg_attr(feature = "serde", derive(Serialize))]
2077pub enum PragmaBody<'bump> {
2078 Equals(PragmaValue<'bump>),
2080 Call(PragmaValue<'bump>),
2082}
2083
2084pub type PragmaValue<'bump> = Expr<'bump>; #[derive(Copy, Clone, Debug, PartialEq, Eq)]
2090#[cfg_attr(feature = "serde", derive(Serialize))]
2091pub enum TriggerTime {
2092 Before, After,
2096 InsteadOf,
2098}
2099
2100#[derive(Debug, PartialEq, Eq)]
2102#[cfg_attr(feature = "serde", derive(Serialize))]
2103pub enum TriggerEvent<'bump> {
2104 Delete,
2106 Insert,
2108 Update,
2110 UpdateOf(DistinctNames<'bump>),
2112}
2113
2114#[derive(Debug, PartialEq, Eq)]
2118#[cfg_attr(feature = "serde", derive(Serialize))]
2119pub enum TriggerCmd<'bump> {
2120 Update {
2122 or_conflict: Option<ResolveType>,
2124 tbl_name: QualifiedName<'bump>,
2126 sets: &'bump [Set<'bump>], from: Option<FromClause<'bump>>,
2130 where_clause: Option<Expr<'bump>>,
2132 },
2133 Insert {
2135 or_conflict: Option<ResolveType>,
2137 tbl_name: QualifiedName<'bump>,
2139 col_names: Option<DistinctNames<'bump>>,
2141 select: &'bump Select<'bump>,
2143 upsert: Option<&'bump Upsert<'bump>>,
2145 },
2146 Delete {
2148 tbl_name: QualifiedName<'bump>,
2150 where_clause: Option<Expr<'bump>>,
2152 },
2153 Select(&'bump Select<'bump>),
2155}
2156
2157#[derive(Copy, Clone, Debug, PartialEq, Eq)]
2159#[cfg_attr(feature = "serde", derive(Serialize))]
2160pub enum ResolveType {
2161 Rollback,
2163 Abort, Fail,
2167 Ignore,
2169 Replace,
2171}
2172
2173#[derive(Debug, PartialEq, Eq)]
2177#[cfg_attr(feature = "serde", derive(Serialize))]
2178pub struct With<'bump> {
2179 pub recursive: bool,
2181 pub ctes: &'bump [CommonTableExpr<'bump>],
2183}
2184
2185#[derive(Clone, Debug, PartialEq, Eq)]
2187#[cfg_attr(feature = "serde", derive(Serialize))]
2188pub enum Materialized {
2189 Any,
2191 Yes,
2193 No,
2195}
2196
2197#[derive(Debug, PartialEq, Eq)]
2200#[cfg_attr(feature = "serde", derive(Serialize))]
2201pub struct CommonTableExpr<'bump> {
2202 pub tbl_name: Name<'bump>,
2204 pub columns: Option<&'bump [IndexedColumn<'bump>]>, pub materialized: Materialized,
2208 pub select: &'bump Select<'bump>,
2210}
2211
2212impl<'bump> CommonTableExpr<'bump> {
2213 pub fn new(
2215 tbl_name: Name<'bump>,
2216 columns: Option<Vec<'bump, IndexedColumn<'bump>>>,
2217 materialized: Materialized,
2218 select: Select<'bump>,
2219 b: &'bump Bump,
2220 ) -> Result<Self, ParserError> {
2221 #[cfg(feature = "extra_checks")]
2222 if let Some(ref columns) = columns {
2223 if let check::ColumnCount::Fixed(cc) = select.column_count() {
2224 if cc as usize != columns.len() {
2225 return Err(custom_err!(
2226 "table {} has {} values for {} columns",
2227 tbl_name,
2228 cc,
2229 columns.len()
2230 ));
2231 }
2232 }
2233 }
2234 Ok(Self {
2235 tbl_name,
2236 columns: columns.map(|cs| cs.into_bump_slice()),
2237 materialized,
2238 select: b.alloc(select),
2239 })
2240 }
2241 pub fn add_cte(ctes: &mut Vec<Self>, cte: Self) -> Result<(), ParserError> {
2243 #[cfg(feature = "extra_checks")]
2244 if ctes.iter().any(|c| c.tbl_name == cte.tbl_name) {
2245 return Err(custom_err!("duplicate WITH table name: {}", cte.tbl_name));
2246 }
2247 ctes.push(cte);
2248 Ok(())
2249 }
2250}
2251
2252#[derive(Debug, PartialEq, Eq)]
2255#[cfg_attr(feature = "serde", derive(Serialize))]
2256pub struct Type<'bump> {
2257 pub name: &'bump str, pub size: Option<TypeSize<'bump>>,
2261}
2262
2263#[derive(Debug, PartialEq, Eq)]
2266#[cfg_attr(feature = "serde", derive(Serialize))]
2267pub enum TypeSize<'bump> {
2268 MaxSize(&'bump Expr<'bump>),
2270 TypeSize(&'bump Expr<'bump>, &'bump Expr<'bump>),
2272}
2273
2274#[derive(Copy, Clone, Debug, PartialEq, Eq)]
2276#[cfg_attr(feature = "serde", derive(Serialize))]
2277pub enum TransactionType {
2278 Deferred, Immediate,
2282 Exclusive,
2284}
2285
2286#[derive(Debug, PartialEq, Eq)]
2290#[cfg_attr(feature = "serde", derive(Serialize))]
2291pub struct Upsert<'bump> {
2292 pub index: Option<UpsertIndex<'bump>>,
2294 pub do_clause: UpsertDo<'bump>,
2296 pub next: Option<&'bump Upsert<'bump>>,
2298}
2299
2300#[derive(Debug, PartialEq, Eq)]
2302#[cfg_attr(feature = "serde", derive(Serialize))]
2303pub struct UpsertIndex<'bump> {
2304 pub targets: &'bump [SortedColumn<'bump>],
2306 pub where_clause: Option<Expr<'bump>>,
2308}
2309
2310impl<'bump> UpsertIndex<'bump> {
2311 pub fn new(
2313 targets: Vec<'bump, SortedColumn<'bump>>,
2314 where_clause: Option<Expr<'bump>>,
2315 ) -> Result<Self, ParserError> {
2316 has_explicit_nulls(&targets)?;
2317 Ok(Self {
2318 targets: targets.into_bump_slice(),
2319 where_clause,
2320 })
2321 }
2322}
2323
2324#[derive(Debug, PartialEq, Eq)]
2326#[cfg_attr(feature = "serde", derive(Serialize))]
2327pub enum UpsertDo<'bump> {
2328 Set {
2330 sets: &'bump [Set<'bump>],
2332 where_clause: Option<Expr<'bump>>,
2334 },
2335 Nothing,
2337}
2338
2339#[derive(Debug, PartialEq, Eq)]
2341#[cfg_attr(feature = "serde", derive(Serialize))]
2342pub struct FunctionTail<'bump> {
2343 pub filter_clause: Option<&'bump Expr<'bump>>,
2345 pub over_clause: Option<&'bump Over<'bump>>,
2347}
2348
2349#[derive(Debug, PartialEq, Eq)]
2352#[cfg_attr(feature = "serde", derive(Serialize))]
2353pub enum Over<'bump> {
2354 Window(&'bump Window<'bump>),
2356 Name(Name<'bump>),
2358}
2359
2360#[derive(Debug, PartialEq, Eq)]
2362#[cfg_attr(feature = "serde", derive(Serialize))]
2363pub struct WindowDef<'bump> {
2364 pub name: Name<'bump>,
2366 pub window: Window<'bump>,
2368}
2369
2370#[derive(Debug, PartialEq, Eq)]
2373#[cfg_attr(feature = "serde", derive(Serialize))]
2374pub struct Window<'bump> {
2375 pub base: Option<Name<'bump>>,
2377 pub partition_by: Option<&'bump [Expr<'bump>]>,
2379 pub order_by: Option<&'bump [SortedColumn<'bump>]>,
2381 pub frame_clause: Option<FrameClause<'bump>>,
2383}
2384
2385impl<'bump> Window<'bump> {
2386 pub fn new(
2388 base: Option<Name<'bump>>,
2389 partition_by: Option<Vec<'bump, Expr<'bump>>>,
2390 order_by: Option<Vec<'bump, SortedColumn<'bump>>>,
2391 frame_clause: Option<FrameClause<'bump>>,
2392 ) -> Self {
2393 Self {
2394 base,
2395 partition_by: partition_by.map(|pb| pb.into_bump_slice()),
2396 order_by: order_by.map(|ob| ob.into_bump_slice()),
2397 frame_clause,
2398 }
2399 }
2400}
2401
2402#[derive(Debug, PartialEq, Eq)]
2405#[cfg_attr(feature = "serde", derive(Serialize))]
2406pub struct FrameClause<'bump> {
2407 pub mode: FrameMode,
2409 pub start: FrameBound<'bump>,
2411 pub end: Option<FrameBound<'bump>>,
2413 pub exclude: Option<FrameExclude>,
2415}
2416
2417#[derive(Copy, Clone, Debug, PartialEq, Eq)]
2419#[cfg_attr(feature = "serde", derive(Serialize))]
2420pub enum FrameMode {
2421 Groups,
2423 Range,
2425 Rows,
2427}
2428
2429#[derive(Debug, PartialEq, Eq)]
2431#[cfg_attr(feature = "serde", derive(Serialize))]
2432pub enum FrameBound<'bump> {
2433 CurrentRow,
2435 Following(Expr<'bump>),
2437 Preceding(Expr<'bump>),
2439 UnboundedFollowing,
2441 UnboundedPreceding,
2443}
2444
2445#[derive(Clone, Debug, PartialEq, Eq)]
2447#[cfg_attr(feature = "serde", derive(Serialize))]
2448pub enum FrameExclude {
2449 NoOthers,
2451 CurrentRow,
2453 Group,
2455 Ties,
2457}
2458
2459#[cfg(test)]
2460mod test {
2461 use super::Name;
2462
2463 #[test]
2464 fn test_dequote() {
2465 let b = bumpalo::Bump::new();
2466 assert_eq!(name("x", &b), "x");
2467 assert_eq!(name("`x`", &b), "x");
2468 assert_eq!(name("`x``y`", &b), "x`y");
2469 assert_eq!(name(r#""x""#, &b), "x");
2470 assert_eq!(name(r#""x""y""#, &b), "x\"y");
2471 assert_eq!(name("[x]", &b), "x");
2472 }
2473
2474 fn name<'bump>(s: &'static str, b: &'bump bumpalo::Bump) -> Name<'bump> {
2475 Name(b.alloc_str(s))
2476 }
2477}