1use std::fmt::{self, Display, Formatter, Write};
4use std::num::ParseIntError;
5use std::str::FromStr;
6
7use indexmap::IndexSet;
8
9use crate::dialect::TokenType::{self, *};
10use crate::dialect::{from_token, is_identifier, Token};
11use crate::parser::{parse::YYCODETYPE, ParserError};
12
13struct FmtTokenStream<'a, 'b> {
14 f: &'a mut Formatter<'b>,
15 spaced: bool,
16}
17impl<'a, 'b> TokenStream for FmtTokenStream<'a, 'b> {
18 type Error = fmt::Error;
19
20 fn append(&mut self, ty: TokenType, value: Option<&str>) -> fmt::Result {
21 if !self.spaced {
22 match ty {
23 TK_COMMA | TK_SEMI | TK_RP | TK_DOT => {}
24 _ => {
25 self.f.write_char(' ')?;
26 self.spaced = true;
27 }
28 };
29 }
30 if ty == TK_BLOB {
31 self.f.write_char('X')?;
32 self.f.write_char('\'')?;
33 if let Some(str) = value {
34 self.f.write_str(str)?;
35 }
36 return self.f.write_char('\'');
37 } else if let Some(str) = ty.as_str() {
38 self.f.write_str(str)?;
39 self.spaced = ty == TK_LP || ty == TK_DOT; }
41 if let Some(str) = value {
42 self.spaced = str.bytes().all(|b| b.is_ascii_whitespace());
44 self.f.write_str(str)
48 } else {
49 Ok(())
50 }
51 }
52}
53
54#[derive(Default)]
55pub struct ParameterInfo {
56 pub count: u32,
57 pub names: IndexSet<String>,
58}
59
60impl TokenStream for ParameterInfo {
62 type Error = ParseIntError;
63
64 fn append(&mut self, ty: TokenType, value: Option<&str>) -> Result<(), Self::Error> {
65 if ty == TK_VARIABLE {
66 if let Some(variable) = value {
67 if variable == "?" {
68 self.count = self.count.saturating_add(1);
69 } else if variable.as_bytes()[0] == b'?' {
70 let n = u32::from_str(&variable[1..])?;
71 if n > self.count {
72 self.count = n;
73 }
74 } else if self.names.insert(variable.to_owned()) {
75 self.count = self.count.saturating_add(1);
76 }
77 }
78 }
79 Ok(())
80 }
81}
82
83pub trait TokenStream {
84 type Error;
85
86 fn append(&mut self, ty: TokenType, value: Option<&str>) -> Result<(), Self::Error>;
87}
88
89pub trait ToTokens {
90 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error>;
91
92 fn to_fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
93 let mut s = FmtTokenStream { f, spaced: true };
94 self.to_tokens(&mut s)
95 }
96}
97
98impl<T: ?Sized + ToTokens> ToTokens for &T {
99 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
100 ToTokens::to_tokens(&**self, s)
101 }
102}
103
104impl ToTokens for String {
105 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
106 s.append(TK_ANY, Some(self.as_ref()))
107 }
108}
109
110#[derive(Clone, Debug, PartialEq, Eq)]
124pub enum Cmd {
125 Explain(Stmt),
126 ExplainQueryPlan(Stmt),
127 Stmt(Stmt),
128}
129
130impl ToTokens for Cmd {
131 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
132 match self {
133 Cmd::Explain(stmt) => {
134 s.append(TK_EXPLAIN, None)?;
135 stmt.to_tokens(s)?;
136 }
137 Cmd::ExplainQueryPlan(stmt) => {
138 s.append(TK_EXPLAIN, None)?;
139 s.append(TK_QUERY, None)?;
140 s.append(TK_PLAN, None)?;
141 stmt.to_tokens(s)?;
142 }
143 Cmd::Stmt(stmt) => {
144 stmt.to_tokens(s)?;
145 }
146 }
147 s.append(TK_SEMI, None)
148 }
149}
150
151impl Display for Cmd {
152 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
153 self.to_fmt(f)
154 }
155}
156
157pub(crate) enum ExplainKind {
158 Explain,
159 QueryPlan,
160}
161
162#[derive(Clone, Debug, PartialEq, Eq)]
164pub enum Stmt {
165 AlterTable(QualifiedName, AlterTableBody),
167 Analyze(Option<QualifiedName>),
169 Attach {
170 expr: Expr,
172 db_name: Expr,
173 key: Option<Expr>,
174 },
175 Begin(Option<TransactionType>, Option<Name>),
177 Commit(Option<Name>), CreateIndex {
180 unique: bool,
181 if_not_exists: bool,
182 idx_name: QualifiedName,
183 tbl_name: Name,
184 columns: Vec<SortedColumn>,
185 where_clause: Option<Expr>,
186 },
187 CreateTable {
188 temporary: bool, if_not_exists: bool,
190 tbl_name: QualifiedName,
191 body: CreateTableBody,
192 },
193 CreateTrigger {
194 temporary: bool,
195 if_not_exists: bool,
196 trigger_name: QualifiedName,
197 time: Option<TriggerTime>,
198 event: TriggerEvent,
199 tbl_name: QualifiedName,
200 for_each_row: bool,
201 when_clause: Option<Expr>,
202 commands: Vec<TriggerCmd>,
203 },
204 CreateView {
205 temporary: bool,
206 if_not_exists: bool,
207 view_name: QualifiedName,
208 columns: Option<Vec<IndexedColumn>>,
209 select: Select,
210 },
211 CreateVirtualTable {
212 if_not_exists: bool,
213 tbl_name: QualifiedName,
214 module_name: Name,
215 args: Option<Vec<String>>, },
217 Delete {
218 with: Option<With>,
219 tbl_name: QualifiedName,
220 indexed: Option<Indexed>,
221 where_clause: Option<Expr>,
222 returning: Option<Vec<ResultColumn>>,
223 order_by: Option<Vec<SortedColumn>>,
224 limit: Option<Limit>,
225 },
226 Detach(Expr), DropIndex {
229 if_exists: bool,
230 idx_name: QualifiedName,
231 },
232 DropTable {
233 if_exists: bool,
234 tbl_name: QualifiedName,
235 },
236 DropTrigger {
237 if_exists: bool,
238 trigger_name: QualifiedName,
239 },
240 DropView {
241 if_exists: bool,
242 view_name: QualifiedName,
243 },
244 Insert {
245 with: Option<With>,
246 or_conflict: Option<ResolveType>, tbl_name: QualifiedName,
248 columns: Option<Vec<Name>>,
249 body: InsertBody,
250 returning: Option<Vec<ResultColumn>>,
251 },
252 Pragma(QualifiedName, Option<PragmaBody>),
254 Reindex {
255 obj_name: Option<QualifiedName>,
256 },
257 Release(Name), Rollback {
260 tx_name: Option<Name>,
261 savepoint_name: Option<Name>, },
263 Savepoint(Name),
265 Select(Select),
266 Update {
267 with: Option<With>,
268 or_conflict: Option<ResolveType>,
269 tbl_name: QualifiedName,
270 indexed: Option<Indexed>,
271 sets: Vec<Set>,
272 from: Option<FromClause>,
273 where_clause: Option<Expr>,
274 returning: Option<Vec<ResultColumn>>,
275 order_by: Option<Vec<SortedColumn>>,
276 limit: Option<Limit>,
277 },
278 Vacuum(Option<Name>, Option<Expr>),
280}
281
282impl ToTokens for Stmt {
283 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
284 match self {
285 Stmt::AlterTable(tbl_name, body) => {
286 s.append(TK_ALTER, None)?;
287 s.append(TK_TABLE, None)?;
288 tbl_name.to_tokens(s)?;
289 body.to_tokens(s)
290 }
291 Stmt::Analyze(obj_name) => {
292 s.append(TK_ANALYZE, None)?;
293 if let Some(obj_name) = obj_name {
294 obj_name.to_tokens(s)?;
295 }
296 Ok(())
297 }
298 Stmt::Attach { expr, db_name, key } => {
299 s.append(TK_ATTACH, None)?;
300 expr.to_tokens(s)?;
301 s.append(TK_AS, None)?;
302 db_name.to_tokens(s)?;
303 if let Some(key) = key {
304 s.append(TK_KEY, None)?;
305 key.to_tokens(s)?;
306 }
307 Ok(())
308 }
309 Stmt::Begin(tx_type, tx_name) => {
310 s.append(TK_BEGIN, None)?;
311 if let Some(tx_type) = tx_type {
312 tx_type.to_tokens(s)?;
313 }
314 if let Some(tx_name) = tx_name {
315 s.append(TK_TRANSACTION, None)?;
316 tx_name.to_tokens(s)?;
317 }
318 Ok(())
319 }
320 Stmt::Commit(tx_name) => {
321 s.append(TK_COMMIT, None)?;
322 if let Some(tx_name) = tx_name {
323 s.append(TK_TRANSACTION, None)?;
324 tx_name.to_tokens(s)?;
325 }
326 Ok(())
327 }
328 Stmt::CreateIndex {
329 unique,
330 if_not_exists,
331 idx_name,
332 tbl_name,
333 columns,
334 where_clause,
335 } => {
336 s.append(TK_CREATE, None)?;
337 if *unique {
338 s.append(TK_UNIQUE, None)?;
339 }
340 s.append(TK_INDEX, None)?;
341 if *if_not_exists {
342 s.append(TK_IF, None)?;
343 s.append(TK_NOT, None)?;
344 s.append(TK_EXISTS, None)?;
345 }
346 idx_name.to_tokens(s)?;
347 s.append(TK_ON, None)?;
348 tbl_name.to_tokens(s)?;
349 s.append(TK_LP, None)?;
350 comma(columns, s)?;
351 s.append(TK_RP, None)?;
352 if let Some(where_clause) = where_clause {
353 s.append(TK_WHERE, None)?;
354 where_clause.to_tokens(s)?;
355 }
356 Ok(())
357 }
358 Stmt::CreateTable {
359 temporary,
360 if_not_exists,
361 tbl_name,
362 body,
363 } => {
364 s.append(TK_CREATE, None)?;
365 if *temporary {
366 s.append(TK_TEMP, None)?;
367 }
368 s.append(TK_TABLE, None)?;
369 if *if_not_exists {
370 s.append(TK_IF, None)?;
371 s.append(TK_NOT, None)?;
372 s.append(TK_EXISTS, None)?;
373 }
374 tbl_name.to_tokens(s)?;
375 body.to_tokens(s)
376 }
377 Stmt::CreateTrigger {
378 temporary,
379 if_not_exists,
380 trigger_name,
381 time,
382 event,
383 tbl_name,
384 for_each_row,
385 when_clause,
386 commands,
387 } => {
388 s.append(TK_CREATE, None)?;
389 if *temporary {
390 s.append(TK_TEMP, None)?;
391 }
392 s.append(TK_TRIGGER, None)?;
393 if *if_not_exists {
394 s.append(TK_IF, None)?;
395 s.append(TK_NOT, None)?;
396 s.append(TK_EXISTS, None)?;
397 }
398 trigger_name.to_tokens(s)?;
399 if let Some(time) = time {
400 time.to_tokens(s)?;
401 }
402 event.to_tokens(s)?;
403 s.append(TK_ON, None)?;
404 tbl_name.to_tokens(s)?;
405 if *for_each_row {
406 s.append(TK_FOR, None)?;
407 s.append(TK_EACH, None)?;
408 s.append(TK_ROW, None)?;
409 }
410 if let Some(when_clause) = when_clause {
411 s.append(TK_WHEN, None)?;
412 when_clause.to_tokens(s)?;
413 }
414 s.append(TK_BEGIN, Some("\n"))?;
415 for command in commands {
416 command.to_tokens(s)?;
417 s.append(TK_SEMI, Some("\n"))?;
418 }
419 s.append(TK_END, None)
420 }
421 Stmt::CreateView {
422 temporary,
423 if_not_exists,
424 view_name,
425 columns,
426 select,
427 } => {
428 s.append(TK_CREATE, None)?;
429 if *temporary {
430 s.append(TK_TEMP, None)?;
431 }
432 s.append(TK_VIEW, None)?;
433 if *if_not_exists {
434 s.append(TK_IF, None)?;
435 s.append(TK_NOT, None)?;
436 s.append(TK_EXISTS, None)?;
437 }
438 view_name.to_tokens(s)?;
439 if let Some(columns) = columns {
440 s.append(TK_LP, None)?;
441 comma(columns, s)?;
442 s.append(TK_RP, None)?;
443 }
444 s.append(TK_AS, None)?;
445 select.to_tokens(s)
446 }
447 Stmt::CreateVirtualTable {
448 if_not_exists,
449 tbl_name,
450 module_name,
451 args,
452 } => {
453 s.append(TK_CREATE, None)?;
454 s.append(TK_VIRTUAL, None)?;
455 s.append(TK_TABLE, None)?;
456 if *if_not_exists {
457 s.append(TK_IF, None)?;
458 s.append(TK_NOT, None)?;
459 s.append(TK_EXISTS, None)?;
460 }
461 tbl_name.to_tokens(s)?;
462 s.append(TK_USING, None)?;
463 module_name.to_tokens(s)?;
464 s.append(TK_LP, None)?;
465 if let Some(args) = args {
466 comma(args, s)?;
467 }
468 s.append(TK_RP, None)
469 }
470 Stmt::Delete {
471 with,
472 tbl_name,
473 indexed,
474 where_clause,
475 returning,
476 order_by,
477 limit,
478 } => {
479 if let Some(with) = with {
480 with.to_tokens(s)?;
481 }
482 s.append(TK_DELETE, None)?;
483 s.append(TK_FROM, None)?;
484 tbl_name.to_tokens(s)?;
485 if let Some(indexed) = indexed {
486 indexed.to_tokens(s)?;
487 }
488 if let Some(where_clause) = where_clause {
489 s.append(TK_WHERE, None)?;
490 where_clause.to_tokens(s)?;
491 }
492 if let Some(returning) = returning {
493 s.append(TK_RETURNING, None)?;
494 comma(returning, s)?;
495 }
496 if let Some(order_by) = order_by {
497 s.append(TK_ORDER, None)?;
498 s.append(TK_BY, None)?;
499 comma(order_by, s)?;
500 }
501 if let Some(limit) = limit {
502 limit.to_tokens(s)?;
503 }
504 Ok(())
505 }
506 Stmt::Detach(expr) => {
507 s.append(TK_DETACH, None)?;
508 expr.to_tokens(s)
509 }
510 Stmt::DropIndex {
511 if_exists,
512 idx_name,
513 } => {
514 s.append(TK_DROP, None)?;
515 s.append(TK_INDEX, None)?;
516 if *if_exists {
517 s.append(TK_IF, None)?;
518 s.append(TK_EXISTS, None)?;
519 }
520 idx_name.to_tokens(s)
521 }
522 Stmt::DropTable {
523 if_exists,
524 tbl_name,
525 } => {
526 s.append(TK_DROP, None)?;
527 s.append(TK_TABLE, None)?;
528 if *if_exists {
529 s.append(TK_IF, None)?;
530 s.append(TK_EXISTS, None)?;
531 }
532 tbl_name.to_tokens(s)
533 }
534 Stmt::DropTrigger {
535 if_exists,
536 trigger_name,
537 } => {
538 s.append(TK_DROP, None)?;
539 s.append(TK_TRIGGER, None)?;
540 if *if_exists {
541 s.append(TK_IF, None)?;
542 s.append(TK_EXISTS, None)?;
543 }
544 trigger_name.to_tokens(s)
545 }
546 Stmt::DropView {
547 if_exists,
548 view_name,
549 } => {
550 s.append(TK_DROP, None)?;
551 s.append(TK_VIEW, None)?;
552 if *if_exists {
553 s.append(TK_IF, None)?;
554 s.append(TK_EXISTS, None)?;
555 }
556 view_name.to_tokens(s)
557 }
558 Stmt::Insert {
559 with,
560 or_conflict,
561 tbl_name,
562 columns,
563 body,
564 returning,
565 } => {
566 if let Some(with) = with {
567 with.to_tokens(s)?;
568 }
569 if let Some(ResolveType::Replace) = or_conflict {
570 s.append(TK_REPLACE, None)?;
571 } else {
572 s.append(TK_INSERT, None)?;
573 if let Some(or_conflict) = or_conflict {
574 s.append(TK_OR, None)?;
575 or_conflict.to_tokens(s)?;
576 }
577 }
578 s.append(TK_INTO, None)?;
579 tbl_name.to_tokens(s)?;
580 if let Some(columns) = columns {
581 s.append(TK_LP, None)?;
582 comma(columns, s)?;
583 s.append(TK_RP, None)?;
584 }
585 body.to_tokens(s)?;
586 if let Some(returning) = returning {
587 s.append(TK_RETURNING, None)?;
588 comma(returning, s)?;
589 }
590 Ok(())
591 }
592 Stmt::Pragma(name, value) => {
593 s.append(TK_PRAGMA, None)?;
594 name.to_tokens(s)?;
595 if let Some(value) = value {
596 value.to_tokens(s)?;
597 }
598 Ok(())
599 }
600 Stmt::Reindex { obj_name } => {
601 s.append(TK_REINDEX, None)?;
602 if let Some(obj_name) = obj_name {
603 obj_name.to_tokens(s)?;
604 }
605 Ok(())
606 }
607 Stmt::Release(name) => {
608 s.append(TK_RELEASE, None)?;
609 name.to_tokens(s)
610 }
611 Stmt::Rollback {
612 tx_name,
613 savepoint_name,
614 } => {
615 s.append(TK_ROLLBACK, None)?;
616 if let Some(tx_name) = tx_name {
617 s.append(TK_TRANSACTION, None)?;
618 tx_name.to_tokens(s)?;
619 }
620 if let Some(savepoint_name) = savepoint_name {
621 s.append(TK_TO, None)?;
622 savepoint_name.to_tokens(s)?;
623 }
624 Ok(())
625 }
626 Stmt::Savepoint(name) => {
627 s.append(TK_SAVEPOINT, None)?;
628 name.to_tokens(s)
629 }
630 Stmt::Select(select) => select.to_tokens(s),
631 Stmt::Update {
632 with,
633 or_conflict,
634 tbl_name,
635 indexed,
636 sets,
637 from,
638 where_clause,
639 returning,
640 order_by,
641 limit,
642 } => {
643 if let Some(with) = with {
644 with.to_tokens(s)?;
645 }
646 s.append(TK_UPDATE, None)?;
647 if let Some(or_conflict) = or_conflict {
648 s.append(TK_OR, None)?;
649 or_conflict.to_tokens(s)?;
650 }
651 tbl_name.to_tokens(s)?;
652 if let Some(indexed) = indexed {
653 indexed.to_tokens(s)?;
654 }
655 s.append(TK_SET, None)?;
656 comma(sets, s)?;
657 if let Some(from) = from {
658 s.append(TK_FROM, None)?;
659 from.to_tokens(s)?;
660 }
661 if let Some(where_clause) = where_clause {
662 s.append(TK_WHERE, None)?;
663 where_clause.to_tokens(s)?;
664 }
665 if let Some(returning) = returning {
666 s.append(TK_RETURNING, None)?;
667 comma(returning, s)?;
668 }
669 if let Some(order_by) = order_by {
670 s.append(TK_ORDER, None)?;
671 s.append(TK_BY, None)?;
672 comma(order_by, s)?;
673 }
674 if let Some(limit) = limit {
675 limit.to_tokens(s)?;
676 }
677 Ok(())
678 }
679 Stmt::Vacuum(name, expr) => {
680 s.append(TK_VACUUM, None)?;
681 if let Some(ref name) = name {
682 name.to_tokens(s)?;
683 }
684 if let Some(ref expr) = expr {
685 s.append(TK_INTO, None)?;
686 expr.to_tokens(s)?;
687 }
688 Ok(())
689 }
690 }
691 }
692}
693
694#[derive(Clone, Debug, PartialEq, Eq)]
696pub enum Expr {
697 Between {
698 lhs: Box<Expr>,
699 not: bool,
700 start: Box<Expr>,
701 end: Box<Expr>,
702 },
703 Binary(Box<Expr>, Operator, Box<Expr>),
704 Case {
706 base: Option<Box<Expr>>,
707 when_then_pairs: Vec<(Expr, Expr)>,
708 else_expr: Option<Box<Expr>>,
709 },
710 Cast {
712 expr: Box<Expr>,
713 type_name: Type,
714 },
715 Collate(Box<Expr>, String),
717 DoublyQualified(Name, Name, Name),
719 Exists(Box<Select>),
721 FunctionCall {
723 name: Id,
724 distinctness: Option<Distinctness>,
725 args: Option<Vec<Expr>>,
726 filter_over: Option<FunctionTail>,
727 },
728 FunctionCallStar {
730 name: Id,
731 filter_over: Option<FunctionTail>,
732 },
733 Id(Id),
735 InList {
736 lhs: Box<Expr>,
737 not: bool,
738 rhs: Option<Vec<Expr>>,
739 },
740 InSelect {
741 lhs: Box<Expr>,
742 not: bool,
743 rhs: Box<Select>,
744 },
745 InTable {
746 lhs: Box<Expr>,
747 not: bool,
748 rhs: QualifiedName,
749 args: Option<Vec<Expr>>,
750 },
751 IsNull(Box<Expr>),
752 Like {
753 lhs: Box<Expr>,
754 not: bool,
755 op: LikeOperator,
756 rhs: Box<Expr>,
757 escape: Option<Box<Expr>>,
758 },
759 Literal(Literal),
761 Name(Name),
762 NotNull(Box<Expr>),
764 Parenthesized(Vec<Expr>),
766 Qualified(Name, Name),
767 Raise(ResolveType, Option<Name>),
769 Subquery(Box<Select>),
771 Unary(UnaryOperator, Box<Expr>),
773 Variable(String),
775}
776
777impl Expr {
778 pub fn parenthesized(x: Expr) -> Expr {
779 Expr::Parenthesized(vec![x])
780 }
781 pub fn id(xt: YYCODETYPE, x: Token) -> Expr {
782 Expr::Id(Id::from_token(xt, x))
783 }
784 pub fn collate(x: Expr, ct: YYCODETYPE, c: Token) -> Expr {
785 Expr::Collate(Box::new(x), from_token(ct, c))
786 }
787 pub fn cast(x: Expr, type_name: Type) -> Expr {
788 Expr::Cast {
789 expr: Box::new(x),
790 type_name,
791 }
792 }
793 pub fn binary(left: Expr, op: YYCODETYPE, right: Expr) -> Expr {
794 Expr::Binary(Box::new(left), Operator::from(op), Box::new(right))
795 }
796 pub fn ptr(left: Expr, op: Token, right: Expr) -> Expr {
797 let mut ptr = Operator::ArrowRight;
798 if let Some(ref op) = op.1 {
799 if op == "->>" {
800 ptr = Operator::ArrowRightShift;
801 }
802 }
803 Expr::Binary(Box::new(left), ptr, Box::new(right))
804 }
805 pub fn like(lhs: Expr, not: bool, op: LikeOperator, rhs: Expr, escape: Option<Expr>) -> Expr {
806 Expr::Like {
807 lhs: Box::new(lhs),
808 not,
809 op,
810 rhs: Box::new(rhs),
811 escape: escape.map(Box::new),
812 }
813 }
814 pub fn not_null(x: Expr, op: YYCODETYPE) -> Expr {
815 if op == TK_ISNULL as YYCODETYPE {
816 Expr::IsNull(Box::new(x))
817 } else if op == TK_NOTNULL as YYCODETYPE {
818 Expr::NotNull(Box::new(x))
819 } else {
820 unreachable!()
821 }
822 }
823 pub fn unary(op: UnaryOperator, x: Expr) -> Expr {
824 Expr::Unary(op, Box::new(x))
825 }
826 pub fn between(lhs: Expr, not: bool, start: Expr, end: Expr) -> Expr {
827 Expr::Between {
828 lhs: Box::new(lhs),
829 not,
830 start: Box::new(start),
831 end: Box::new(end),
832 }
833 }
834 pub fn in_list(lhs: Expr, not: bool, rhs: Option<Vec<Expr>>) -> Expr {
835 Expr::InList {
836 lhs: Box::new(lhs),
837 not,
838 rhs,
839 }
840 }
841 pub fn in_select(lhs: Expr, not: bool, rhs: Select) -> Expr {
842 Expr::InSelect {
843 lhs: Box::new(lhs),
844 not,
845 rhs: Box::new(rhs),
846 }
847 }
848 pub fn in_table(lhs: Expr, not: bool, rhs: QualifiedName, args: Option<Vec<Expr>>) -> Expr {
849 Expr::InTable {
850 lhs: Box::new(lhs),
851 not,
852 rhs,
853 args,
854 }
855 }
856 pub fn sub_query(query: Select) -> Expr {
857 Expr::Subquery(Box::new(query))
858 }
859}
860impl ToTokens for Expr {
861 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
862 match self {
863 Expr::Between {
864 lhs,
865 not,
866 start,
867 end,
868 } => {
869 lhs.to_tokens(s)?;
870 if *not {
871 s.append(TK_NOT, None)?;
872 }
873 s.append(TK_BETWEEN, None)?;
874 start.to_tokens(s)?;
875 s.append(TK_AND, None)?;
876 end.to_tokens(s)
877 }
878 Expr::Binary(lhs, op, rhs) => {
879 lhs.to_tokens(s)?;
880 op.to_tokens(s)?;
881 rhs.to_tokens(s)
882 }
883 Expr::Case {
884 base,
885 when_then_pairs,
886 else_expr,
887 } => {
888 s.append(TK_CASE, None)?;
889 if let Some(ref base) = base {
890 base.to_tokens(s)?;
891 }
892 for (when, then) in when_then_pairs {
893 s.append(TK_WHEN, None)?;
894 when.to_tokens(s)?;
895 s.append(TK_THEN, None)?;
896 then.to_tokens(s)?;
897 }
898 if let Some(ref else_expr) = else_expr {
899 s.append(TK_ELSE, None)?;
900 else_expr.to_tokens(s)?;
901 }
902 s.append(TK_END, None)
903 }
904 Expr::Cast { expr, type_name } => {
905 s.append(TK_CAST, None)?;
906 s.append(TK_LP, None)?;
907 expr.to_tokens(s)?;
908 s.append(TK_AS, None)?;
909 type_name.to_tokens(s)?;
910 s.append(TK_RP, None)
911 }
912 Expr::Collate(expr, collation) => {
913 expr.to_tokens(s)?;
914 s.append(TK_COLLATE, None)?;
915 double_quote(collation, s)
916 }
917 Expr::DoublyQualified(db_name, tbl_name, col_name) => {
918 db_name.to_tokens(s)?;
919 s.append(TK_DOT, None)?;
920 tbl_name.to_tokens(s)?;
921 s.append(TK_DOT, None)?;
922 col_name.to_tokens(s)
923 }
924 Expr::Exists(subquery) => {
925 s.append(TK_EXISTS, None)?;
926 s.append(TK_LP, None)?;
927 subquery.to_tokens(s)?;
928 s.append(TK_RP, None)
929 }
930 Expr::FunctionCall {
931 name,
932 distinctness,
933 args,
934 filter_over,
935 } => {
936 name.to_tokens(s)?;
937 s.append(TK_LP, None)?;
938 if let Some(distinctness) = distinctness {
939 distinctness.to_tokens(s)?;
940 }
941 if let Some(args) = args {
942 comma(args, s)?;
943 }
944 s.append(TK_RP, None)?;
945 if let Some(filter_over) = filter_over {
946 filter_over.to_tokens(s)?;
947 }
948 Ok(())
949 }
950 Expr::FunctionCallStar { name, filter_over } => {
951 name.to_tokens(s)?;
952 s.append(TK_LP, None)?;
953 s.append(TK_STAR, None)?;
954 s.append(TK_RP, None)?;
955 if let Some(filter_over) = filter_over {
956 filter_over.to_tokens(s)?;
957 }
958 Ok(())
959 }
960 Expr::Id(id) => id.to_tokens(s),
961 Expr::InList { lhs, not, rhs } => {
962 lhs.to_tokens(s)?;
963 if *not {
964 s.append(TK_NOT, None)?;
965 }
966 s.append(TK_IN, None)?;
967 s.append(TK_LP, None)?;
968 if let Some(rhs) = rhs {
969 comma(rhs, s)?;
970 }
971 s.append(TK_RP, None)
972 }
973 Expr::InSelect { lhs, not, rhs } => {
974 lhs.to_tokens(s)?;
975 if *not {
976 s.append(TK_NOT, None)?;
977 }
978 s.append(TK_IN, None)?;
979 s.append(TK_LP, None)?;
980 rhs.to_tokens(s)?;
981 s.append(TK_RP, None)
982 }
983 Expr::InTable {
984 lhs,
985 not,
986 rhs,
987 args,
988 } => {
989 lhs.to_tokens(s)?;
990 if *not {
991 s.append(TK_NOT, None)?;
992 }
993 s.append(TK_IN, None)?;
994 rhs.to_tokens(s)?;
995 if let Some(args) = args {
996 s.append(TK_LP, None)?;
997 comma(args, s)?;
998 s.append(TK_RP, None)?;
999 }
1000 Ok(())
1001 }
1002 Expr::IsNull(sub_expr) => {
1003 sub_expr.to_tokens(s)?;
1004 s.append(TK_ISNULL, None)
1005 }
1006 Expr::Like {
1007 lhs,
1008 not,
1009 op,
1010 rhs,
1011 escape,
1012 } => {
1013 lhs.to_tokens(s)?;
1014 if *not {
1015 s.append(TK_NOT, None)?;
1016 }
1017 op.to_tokens(s)?;
1018 rhs.to_tokens(s)?;
1019 if let Some(escape) = escape {
1020 s.append(TK_ESCAPE, None)?;
1021 escape.to_tokens(s)?;
1022 }
1023 Ok(())
1024 }
1025 Expr::Literal(lit) => lit.to_tokens(s),
1026 Expr::Name(name) => name.to_tokens(s),
1027 Expr::NotNull(sub_expr) => {
1028 sub_expr.to_tokens(s)?;
1029 s.append(TK_NOTNULL, None)
1030 }
1031 Expr::Parenthesized(exprs) => {
1032 s.append(TK_LP, None)?;
1033 comma(exprs, s)?;
1034 s.append(TK_RP, None)
1035 }
1036 Expr::Qualified(qualifier, qualified) => {
1037 qualifier.to_tokens(s)?;
1038 s.append(TK_DOT, None)?;
1039 qualified.to_tokens(s)
1040 }
1041 Expr::Raise(rt, err) => {
1042 s.append(TK_RAISE, None)?;
1043 s.append(TK_LP, None)?;
1044 rt.to_tokens(s)?;
1045 if let Some(err) = err {
1046 s.append(TK_COMMA, None)?;
1047 err.to_tokens(s)?;
1048 }
1049 s.append(TK_RP, None)
1050 }
1051 Expr::Subquery(query) => {
1052 s.append(TK_LP, None)?;
1053 query.to_tokens(s)?;
1054 s.append(TK_RP, None)
1055 }
1056 Expr::Unary(op, sub_expr) => {
1057 op.to_tokens(s)?;
1058 sub_expr.to_tokens(s)
1059 }
1060 Expr::Variable(var) => match var.chars().next() {
1061 Some(c) if c == '$' || c == '@' || c == '#' || c == ':' => {
1062 s.append(TK_VARIABLE, Some(var))
1063 }
1064 Some(_) => s.append(TK_VARIABLE, Some(&("?".to_owned() + var))),
1065 None => s.append(TK_VARIABLE, Some("?")),
1066 },
1067 }
1068 }
1069}
1070
1071impl Display for Expr {
1072 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1073 self.to_fmt(f)
1074 }
1075}
1076
1077#[derive(Clone, Debug, PartialEq, Eq)]
1078pub enum Literal {
1079 Numeric(String),
1080 String(String),
1082 Blob(String),
1084 Keyword(String),
1085 Null,
1086 CurrentDate,
1087 CurrentTime,
1088 CurrentTimestamp,
1089}
1090
1091impl Literal {
1092 pub fn from_ctime_kw(token: Token) -> Literal {
1093 if let Some(ref token) = token.1 {
1094 if "CURRENT_DATE".eq_ignore_ascii_case(token) {
1095 Literal::CurrentDate
1096 } else if "CURRENT_TIME".eq_ignore_ascii_case(token) {
1097 Literal::CurrentTime
1098 } else if "CURRENT_TIMESTAMP".eq_ignore_ascii_case(token) {
1099 Literal::CurrentTimestamp
1100 } else {
1101 unreachable!()
1102 }
1103 } else {
1104 unreachable!()
1105 }
1106 }
1107}
1108impl ToTokens for Literal {
1109 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1110 match self {
1111 Literal::Numeric(ref num) => s.append(TK_FLOAT, Some(num)), Literal::String(ref str) => s.append(TK_STRING, Some(str)),
1113 Literal::Blob(ref blob) => s.append(TK_BLOB, Some(blob)),
1114 Literal::Keyword(ref str) => s.append(TK_ID, Some(str)), Literal::Null => s.append(TK_NULL, None),
1116 Literal::CurrentDate => s.append(TK_CTIME_KW, Some("CURRENT_DATE")),
1117 Literal::CurrentTime => s.append(TK_CTIME_KW, Some("CURRENT_TIME")),
1118 Literal::CurrentTimestamp => s.append(TK_CTIME_KW, Some("CURRENT_TIMESTAMP")),
1119 }
1120 }
1121}
1122
1123#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1124pub enum LikeOperator {
1125 Glob,
1126 Like,
1127 Match,
1128 Regexp,
1129}
1130
1131impl LikeOperator {
1132 pub fn from_token(token_type: YYCODETYPE, token: Token) -> LikeOperator {
1133 if token_type == TK_MATCH as YYCODETYPE {
1134 return LikeOperator::Match;
1135 } else if token_type == TK_LIKE_KW as YYCODETYPE {
1136 if let Some(ref token) = token.1 {
1137 if "LIKE".eq_ignore_ascii_case(token) {
1138 return LikeOperator::Like;
1139 } else if "GLOB".eq_ignore_ascii_case(token) {
1140 return LikeOperator::Glob;
1141 } else if "REGEXP".eq_ignore_ascii_case(token) {
1142 return LikeOperator::Regexp;
1143 }
1144 }
1145 }
1146 unreachable!()
1147 }
1148}
1149impl ToTokens for LikeOperator {
1150 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1151 s.append(
1152 TK_LIKE_KW,
1153 Some(match self {
1154 LikeOperator::Glob => "GLOB",
1155 LikeOperator::Like => "LIKE",
1156 LikeOperator::Match => "MATCH",
1157 LikeOperator::Regexp => "REGEXP",
1158 }),
1159 )
1160 }
1161}
1162
1163#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1164pub enum Operator {
1165 Add,
1166 And,
1167 ArrowRight, ArrowRightShift, BitwiseAnd,
1170 BitwiseOr,
1171 Concat, Equals, Divide,
1174 Greater,
1175 GreaterEquals,
1176 Is,
1177 IsNot,
1178 LeftShift,
1179 Less,
1180 LessEquals,
1181 Modulus,
1182 Multiply,
1183 NotEquals, Or,
1185 RightShift,
1186 Substract,
1187}
1188
1189impl From<YYCODETYPE> for Operator {
1190 fn from(token_type: YYCODETYPE) -> Operator {
1191 match token_type {
1192 x if x == TK_AND as YYCODETYPE => Operator::And,
1193 x if x == TK_OR as YYCODETYPE => Operator::Or,
1194 x if x == TK_LT as YYCODETYPE => Operator::Less,
1195 x if x == TK_GT as YYCODETYPE => Operator::Greater,
1196 x if x == TK_GE as YYCODETYPE => Operator::GreaterEquals,
1197 x if x == TK_LE as YYCODETYPE => Operator::LessEquals,
1198 x if x == TK_EQ as YYCODETYPE => Operator::Equals,
1199 x if x == TK_NE as YYCODETYPE => Operator::NotEquals,
1200 x if x == TK_BITAND as YYCODETYPE => Operator::BitwiseAnd,
1201 x if x == TK_BITOR as YYCODETYPE => Operator::BitwiseOr,
1202 x if x == TK_LSHIFT as YYCODETYPE => Operator::LeftShift,
1203 x if x == TK_RSHIFT as YYCODETYPE => Operator::RightShift,
1204 x if x == TK_PLUS as YYCODETYPE => Operator::Add,
1205 x if x == TK_MINUS as YYCODETYPE => Operator::Substract,
1206 x if x == TK_STAR as YYCODETYPE => Operator::Multiply,
1207 x if x == TK_SLASH as YYCODETYPE => Operator::Divide,
1208 x if x == TK_REM as YYCODETYPE => Operator::Modulus,
1209 x if x == TK_CONCAT as YYCODETYPE => Operator::Concat,
1210 x if x == TK_IS as YYCODETYPE => Operator::Is,
1211 x if x == TK_NOT as YYCODETYPE => Operator::IsNot,
1212 _ => unreachable!(),
1213 }
1214 }
1215}
1216impl ToTokens for Operator {
1217 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1218 match self {
1219 Operator::Add => s.append(TK_PLUS, None),
1220 Operator::And => s.append(TK_AND, None),
1221 Operator::ArrowRight => s.append(TK_PTR, Some("->")),
1222 Operator::ArrowRightShift => s.append(TK_PTR, Some("->>")),
1223 Operator::BitwiseAnd => s.append(TK_BITAND, None),
1224 Operator::BitwiseOr => s.append(TK_BITOR, None),
1225 Operator::Concat => s.append(TK_CONCAT, None),
1226 Operator::Equals => s.append(TK_EQ, None),
1227 Operator::Divide => s.append(TK_SLASH, None),
1228 Operator::Greater => s.append(TK_GT, None),
1229 Operator::GreaterEquals => s.append(TK_GE, None),
1230 Operator::Is => s.append(TK_IS, None),
1231 Operator::IsNot => {
1232 s.append(TK_IS, None)?;
1233 s.append(TK_NOT, None)
1234 }
1235 Operator::LeftShift => s.append(TK_LSHIFT, None),
1236 Operator::Less => s.append(TK_LT, None),
1237 Operator::LessEquals => s.append(TK_LE, None),
1238 Operator::Modulus => s.append(TK_REM, None),
1239 Operator::Multiply => s.append(TK_STAR, None),
1240 Operator::NotEquals => s.append(TK_NE, None),
1241 Operator::Or => s.append(TK_OR, None),
1242 Operator::RightShift => s.append(TK_RSHIFT, None),
1243 Operator::Substract => s.append(TK_MINUS, None),
1244 }
1245 }
1246}
1247
1248#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1249pub enum UnaryOperator {
1250 BitwiseNot,
1252 Negative,
1254 Not,
1256 Positive,
1258}
1259
1260impl From<YYCODETYPE> for UnaryOperator {
1261 fn from(token_type: YYCODETYPE) -> UnaryOperator {
1262 match token_type {
1263 x if x == TK_BITNOT as YYCODETYPE => UnaryOperator::BitwiseNot,
1264 x if x == TK_MINUS as YYCODETYPE => UnaryOperator::Negative,
1265 x if x == TK_NOT as YYCODETYPE => UnaryOperator::Not,
1266 x if x == TK_PLUS as YYCODETYPE => UnaryOperator::Positive,
1267 _ => unreachable!(),
1268 }
1269 }
1270}
1271impl ToTokens for UnaryOperator {
1272 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1273 s.append(
1274 match self {
1275 UnaryOperator::BitwiseNot => TK_BITNOT,
1276 UnaryOperator::Negative => TK_MINUS,
1277 UnaryOperator::Not => TK_NOT,
1278 UnaryOperator::Positive => TK_PLUS,
1279 },
1280 None,
1281 )
1282 }
1283}
1284
1285#[derive(Clone, Debug, PartialEq, Eq)]
1288pub struct Select {
1289 pub with: Option<With>,
1290 pub body: SelectBody,
1291 pub order_by: Option<Vec<SortedColumn>>,
1292 pub limit: Option<Limit>,
1293}
1294impl ToTokens for Select {
1295 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1296 if let Some(ref with) = self.with {
1297 with.to_tokens(s)?;
1298 }
1299 self.body.to_tokens(s)?;
1300 if let Some(ref order_by) = self.order_by {
1301 s.append(TK_ORDER, None)?;
1302 s.append(TK_BY, None)?;
1303 comma(order_by, s)?;
1304 }
1305 if let Some(ref limit) = self.limit {
1306 limit.to_tokens(s)?;
1307 }
1308 Ok(())
1309 }
1310}
1311
1312#[derive(Clone, Debug, PartialEq, Eq)]
1313pub struct SelectBody {
1314 pub select: OneSelect,
1315 pub compounds: Option<Vec<CompoundSelect>>,
1316}
1317
1318impl SelectBody {
1319 pub(crate) fn push(&mut self, cs: CompoundSelect) {
1320 if let Some(ref mut v) = self.compounds {
1321 v.push(cs);
1322 } else {
1323 self.compounds = Some(vec![cs]);
1324 }
1325 }
1326}
1327impl ToTokens for SelectBody {
1328 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1329 self.select.to_tokens(s)?;
1330 if let Some(ref compounds) = self.compounds {
1331 for compound in compounds {
1332 compound.to_tokens(s)?;
1333 }
1334 }
1335 Ok(())
1336 }
1337}
1338
1339#[derive(Clone, Debug, PartialEq, Eq)]
1340pub struct CompoundSelect {
1341 pub operator: CompoundOperator,
1342 pub select: OneSelect,
1343}
1344impl ToTokens for CompoundSelect {
1345 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1346 self.operator.to_tokens(s)?;
1347 self.select.to_tokens(s)
1348 }
1349}
1350
1351#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1353pub enum CompoundOperator {
1354 Union,
1355 UnionAll,
1356 Except,
1357 Intersect,
1358}
1359impl ToTokens for CompoundOperator {
1360 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1361 match self {
1362 CompoundOperator::Union => s.append(TK_UNION, None),
1363 CompoundOperator::UnionAll => {
1364 s.append(TK_UNION, None)?;
1365 s.append(TK_ALL, None)
1366 }
1367 CompoundOperator::Except => s.append(TK_EXCEPT, None),
1368 CompoundOperator::Intersect => s.append(TK_INTERSECT, None),
1369 }
1370 }
1371}
1372
1373#[derive(Clone, Debug, PartialEq, Eq)]
1375pub enum OneSelect {
1376 Select {
1377 distinctness: Option<Distinctness>,
1378 columns: Vec<ResultColumn>,
1379 from: Option<FromClause>,
1380 where_clause: Option<Expr>,
1381 group_by: Option<GroupBy>,
1382 window_clause: Option<Vec<WindowDef>>,
1383 },
1384 Values(Vec<Vec<Expr>>),
1385}
1386impl ToTokens for OneSelect {
1387 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1388 match self {
1389 OneSelect::Select {
1390 distinctness,
1391 columns,
1392 from,
1393 where_clause,
1394 group_by,
1395 window_clause,
1396 } => {
1397 s.append(TK_SELECT, None)?;
1398 if let Some(ref distinctness) = distinctness {
1399 distinctness.to_tokens(s)?;
1400 }
1401 comma(columns, s)?;
1402 if let Some(ref from) = from {
1403 s.append(TK_FROM, None)?;
1404 from.to_tokens(s)?;
1405 }
1406 if let Some(ref where_clause) = where_clause {
1407 s.append(TK_WHERE, None)?;
1408 where_clause.to_tokens(s)?;
1409 }
1410 if let Some(ref group_by) = group_by {
1411 group_by.to_tokens(s)?;
1412 }
1413 if let Some(ref window_clause) = window_clause {
1414 s.append(TK_WINDOW, None)?;
1415 comma(window_clause, s)?;
1416 }
1417 Ok(())
1418 }
1419 OneSelect::Values(values) => {
1420 for (i, vals) in values.iter().enumerate() {
1421 if i == 0 {
1422 s.append(TK_VALUES, None)?;
1423 } else {
1424 s.append(TK_COMMA, None)?;
1425 }
1426 s.append(TK_LP, None)?;
1427 comma(vals, s)?;
1428 s.append(TK_RP, None)?;
1429 }
1430 Ok(())
1431 }
1432 }
1433 }
1434}
1435
1436#[derive(Clone, Debug, PartialEq, Eq)]
1438pub struct FromClause {
1439 pub select: Option<Box<SelectTable>>, pub joins: Option<Vec<JoinedSelectTable>>,
1441 op: Option<JoinOperator>, }
1443impl FromClause {
1444 pub(crate) fn empty() -> FromClause {
1445 FromClause {
1446 select: None,
1447 joins: None,
1448 op: None,
1449 }
1450 }
1451
1452 pub(crate) fn push(
1453 &mut self,
1454 table: SelectTable,
1455 jc: Option<JoinConstraint>,
1456 ) -> Result<(), ParserError> {
1457 let op = self.op.take();
1458 if let Some(op) = op {
1459 let jst = JoinedSelectTable {
1460 operator: op,
1461 table,
1462 constraint: jc,
1463 };
1464 if let Some(ref mut joins) = self.joins {
1465 joins.push(jst);
1466 } else {
1467 self.joins = Some(vec![jst]);
1468 }
1469 } else {
1470 if jc.is_some() {
1471 return Err(ParserError::Custom(
1472 "a JOIN clause is required before ON".to_string(),
1473 ));
1474 }
1475 debug_assert!(self.select.is_none());
1476 debug_assert!(self.joins.is_none());
1477 self.select = Some(Box::new(table));
1478 }
1479
1480 Ok(())
1481 }
1482
1483 pub(crate) fn push_op(&mut self, op: JoinOperator) {
1484 self.op = Some(op);
1485 }
1486}
1487impl ToTokens for FromClause {
1488 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1489 self.select.as_ref().unwrap().to_tokens(s)?;
1490 if let Some(ref joins) = self.joins {
1491 for join in joins {
1492 join.to_tokens(s)?;
1493 }
1494 }
1495 Ok(())
1496 }
1497}
1498
1499#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1500pub enum Distinctness {
1501 Distinct,
1502 All,
1503}
1504impl ToTokens for Distinctness {
1505 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1506 s.append(
1507 match self {
1508 Distinctness::Distinct => TK_DISTINCT,
1509 Distinctness::All => TK_ALL,
1510 },
1511 None,
1512 )
1513 }
1514}
1515
1516#[derive(Clone, Debug, PartialEq, Eq)]
1518pub enum ResultColumn {
1519 Expr(Expr, Option<As>),
1520 Star,
1521 TableStar(Name),
1523}
1524impl ToTokens for ResultColumn {
1525 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1526 match self {
1527 ResultColumn::Expr(expr, alias) => {
1528 expr.to_tokens(s)?;
1529 if let Some(alias) = alias {
1530 alias.to_tokens(s)?;
1531 }
1532 Ok(())
1533 }
1534 ResultColumn::Star => s.append(TK_STAR, None),
1535 ResultColumn::TableStar(tbl_name) => {
1536 tbl_name.to_tokens(s)?;
1537 s.append(TK_DOT, None)?;
1538 s.append(TK_STAR, None)
1539 }
1540 }
1541 }
1542}
1543
1544#[derive(Clone, Debug, PartialEq, Eq)]
1545pub enum As {
1546 As(Name),
1547 Elided(Name), }
1549impl ToTokens for As {
1550 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1551 match self {
1552 As::As(ref name) => {
1553 s.append(TK_AS, None)?;
1554 name.to_tokens(s)
1555 }
1556 As::Elided(ref name) => name.to_tokens(s),
1557 }
1558 }
1559}
1560
1561#[derive(Clone, Debug, PartialEq, Eq)]
1563pub struct JoinedSelectTable {
1564 pub operator: JoinOperator,
1565 pub table: SelectTable,
1566 pub constraint: Option<JoinConstraint>,
1567}
1568impl ToTokens for JoinedSelectTable {
1569 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1570 self.operator.to_tokens(s)?;
1571 self.table.to_tokens(s)?;
1572 if let Some(ref constraint) = self.constraint {
1573 constraint.to_tokens(s)?;
1574 }
1575 Ok(())
1576 }
1577}
1578
1579#[derive(Clone, Debug, PartialEq, Eq)]
1581pub enum SelectTable {
1582 Table(QualifiedName, Option<As>, Option<Indexed>),
1583 TableCall(QualifiedName, Option<Vec<Expr>>, Option<As>),
1584 Select(Select, Option<As>),
1585 Sub(FromClause, Option<As>),
1586}
1587impl ToTokens for SelectTable {
1588 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1589 match self {
1590 SelectTable::Table(name, alias, indexed) => {
1591 name.to_tokens(s)?;
1592 if let Some(alias) = alias {
1593 alias.to_tokens(s)?;
1594 }
1595 if let Some(indexed) = indexed {
1596 indexed.to_tokens(s)?;
1597 }
1598 Ok(())
1599 }
1600 SelectTable::TableCall(name, exprs, alias) => {
1601 name.to_tokens(s)?;
1602 s.append(TK_LP, None)?;
1603 if let Some(exprs) = exprs {
1604 comma(exprs, s)?;
1605 }
1606 s.append(TK_RP, None)?;
1607 if let Some(alias) = alias {
1608 alias.to_tokens(s)?;
1609 }
1610 Ok(())
1611 }
1612 SelectTable::Select(select, alias) => {
1613 s.append(TK_LP, None)?;
1614 select.to_tokens(s)?;
1615 s.append(TK_RP, None)?;
1616 if let Some(alias) = alias {
1617 alias.to_tokens(s)?;
1618 }
1619 Ok(())
1620 }
1621 SelectTable::Sub(from, alias) => {
1622 s.append(TK_LP, None)?;
1623 from.to_tokens(s)?;
1624 s.append(TK_RP, None)?;
1625 if let Some(alias) = alias {
1626 alias.to_tokens(s)?;
1627 }
1628 Ok(())
1629 }
1630 }
1631 }
1632}
1633
1634#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1636pub enum JoinOperator {
1637 Comma,
1638 TypedJoin {
1639 natural: bool,
1640 join_type: Option<JoinType>,
1641 },
1642}
1643
1644impl JoinOperator {
1645 pub(crate) fn from_single(token: Token) -> Result<JoinOperator, ParserError> {
1646 Ok(if let Some(ref jt) = token.1 {
1647 if "CROSS".eq_ignore_ascii_case(jt) {
1648 JoinOperator::TypedJoin {
1649 natural: false,
1650 join_type: Some(JoinType::Cross),
1651 }
1652 } else if "INNER".eq_ignore_ascii_case(jt) {
1653 JoinOperator::TypedJoin {
1654 natural: false,
1655 join_type: Some(JoinType::Inner),
1656 }
1657 } else if "LEFT".eq_ignore_ascii_case(jt) {
1658 JoinOperator::TypedJoin {
1659 natural: false,
1660 join_type: Some(JoinType::Left),
1661 }
1662 } else if "RIGHT".eq_ignore_ascii_case(jt) {
1663 JoinOperator::TypedJoin {
1664 natural: false,
1665 join_type: Some(JoinType::Right),
1666 }
1667 } else if "FULL".eq_ignore_ascii_case(jt) {
1668 JoinOperator::TypedJoin {
1669 natural: false,
1670 join_type: Some(JoinType::Full),
1671 }
1672 } else if "NATURAL".eq_ignore_ascii_case(jt) {
1673 JoinOperator::TypedJoin {
1674 natural: true,
1675 join_type: None,
1676 }
1677 } else {
1678 return Err(ParserError::Custom(format!(
1679 "unsupported JOIN type: {}",
1680 jt
1681 )));
1682 }
1683 } else {
1684 unreachable!()
1685 })
1686 }
1687 pub(crate) fn from_couple(token: Token, name: Name) -> Result<JoinOperator, ParserError> {
1688 Ok(if let Some(ref jt) = token.1 {
1689 if "NATURAL".eq_ignore_ascii_case(jt) {
1690 let join_type = if "INNER".eq_ignore_ascii_case(&name.0) {
1691 JoinType::Inner
1692 } else if "LEFT".eq_ignore_ascii_case(&name.0) {
1693 JoinType::Left
1694 } else if "RIGHT".eq_ignore_ascii_case(&name.0) {
1695 JoinType::Right
1696 } else if "FULL".eq_ignore_ascii_case(&name.0) {
1697 JoinType::Full
1698 } else if "CROSS".eq_ignore_ascii_case(&name.0) {
1699 JoinType::Cross
1700 } else {
1701 return Err(ParserError::Custom(format!(
1702 "unsupported JOIN type: {} {}",
1703 jt, &name.0
1704 )));
1705 };
1706 JoinOperator::TypedJoin {
1707 natural: true,
1708 join_type: Some(join_type),
1709 }
1710 } else if "OUTER".eq_ignore_ascii_case(&name.0) {
1711 let join_type = if "LEFT".eq_ignore_ascii_case(jt) {
1713 JoinType::LeftOuter
1714 } else if "RIGHT".eq_ignore_ascii_case(jt) {
1715 JoinType::RightOuter
1716 } else if "FULL".eq_ignore_ascii_case(jt) {
1717 JoinType::FullOuter
1718 } else {
1719 return Err(ParserError::Custom(format!(
1720 "unsupported JOIN type: {} {}",
1721 jt, &name.0
1722 )));
1723 };
1724 JoinOperator::TypedJoin {
1725 natural: false,
1726 join_type: Some(join_type),
1727 }
1728 } else if "LEFT".eq_ignore_ascii_case(jt) && "RIGHT".eq_ignore_ascii_case(&name.0) {
1729 JoinOperator::TypedJoin {
1730 natural: false,
1731 join_type: Some(JoinType::Full),
1732 }
1733 } else if "OUTER".eq_ignore_ascii_case(jt) && "LEFT".eq_ignore_ascii_case(&name.0) {
1734 JoinOperator::TypedJoin {
1736 natural: false,
1737 join_type: Some(JoinType::LeftOuter),
1738 }
1739 } else {
1740 return Err(ParserError::Custom(format!(
1741 "unsupported JOIN type: {} {}",
1742 jt, &name.0
1743 )));
1744 }
1745 } else {
1746 unreachable!()
1747 })
1748 }
1749 pub(crate) fn from_triple(
1750 token: Token,
1751 n1: Name,
1752 n2: Name,
1753 ) -> Result<JoinOperator, ParserError> {
1754 Ok(if let Some(ref jt) = token.1 {
1755 if "NATURAL".eq_ignore_ascii_case(jt) && "OUTER".eq_ignore_ascii_case(&n2.0) {
1756 let join_type = if "LEFT".eq_ignore_ascii_case(&n1.0) {
1758 JoinType::LeftOuter
1759 } else if "RIGHT".eq_ignore_ascii_case(&n1.0) {
1760 JoinType::RightOuter
1761 } else if "FULL".eq_ignore_ascii_case(&n1.0) {
1762 JoinType::FullOuter
1763 } else {
1764 return Err(ParserError::Custom(format!(
1765 "unsupported JOIN type: {} {} {}",
1766 jt, &n1.0, &n2.0
1767 )));
1768 };
1769 JoinOperator::TypedJoin {
1770 natural: true,
1771 join_type: Some(join_type),
1772 }
1773 } else if "OUTER".eq_ignore_ascii_case(jt)
1774 && "LEFT".eq_ignore_ascii_case(&n1.0)
1775 && "NATURAL".eq_ignore_ascii_case(&n2.0)
1776 {
1777 JoinOperator::TypedJoin {
1778 natural: true,
1779 join_type: Some(JoinType::LeftOuter),
1780 }
1781 } else {
1782 return Err(ParserError::Custom(format!(
1783 "unsupported JOIN type: {} {} {}",
1784 jt, &n1.0, &n2.0
1785 )));
1786 }
1787 } else {
1788 unreachable!()
1789 })
1790 }
1791}
1792impl ToTokens for JoinOperator {
1793 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1794 match self {
1795 JoinOperator::Comma => s.append(TK_COMMA, None),
1796 JoinOperator::TypedJoin { natural, join_type } => {
1797 if *natural {
1798 s.append(TK_JOIN_KW, Some("NATURAL"))?;
1799 }
1800 if let Some(ref join_type) = join_type {
1801 join_type.to_tokens(s)?;
1802 }
1803 s.append(TK_JOIN, None)
1804 }
1805 }
1806 }
1807}
1808
1809#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1810pub enum JoinType {
1811 Left, LeftOuter,
1813 Inner,
1814 Cross,
1815 Right, RightOuter,
1817 Full, FullOuter,
1819}
1820impl ToTokens for JoinType {
1821 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1822 s.append(
1823 TK_JOIN_KW,
1824 match self {
1825 JoinType::Left => Some("LEFT"),
1826 JoinType::LeftOuter => Some("LEFT OUTER"),
1827 JoinType::Inner => Some("INNER"),
1828 JoinType::Cross => Some("CROSS"),
1829 JoinType::Right => Some("RIGHT"),
1830 JoinType::RightOuter => Some("RIGHT OUTER"),
1831 JoinType::Full => Some("FULL"),
1832 JoinType::FullOuter => Some("FULL OUTER"),
1833 },
1834 )
1835 }
1836}
1837
1838#[derive(Clone, Debug, PartialEq, Eq)]
1839pub enum JoinConstraint {
1840 On(Expr),
1841 Using(Vec<Name>),
1843}
1844
1845impl ToTokens for JoinConstraint {
1846 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1847 match self {
1848 JoinConstraint::On(expr) => {
1849 s.append(TK_ON, None)?;
1850 expr.to_tokens(s)
1851 }
1852 JoinConstraint::Using(col_names) => {
1853 s.append(TK_USING, None)?;
1854 s.append(TK_LP, None)?;
1855 comma(col_names, s)?;
1856 s.append(TK_RP, None)
1857 }
1858 }
1859 }
1860}
1861
1862#[derive(Clone, Debug, PartialEq, Eq)]
1863pub struct GroupBy {
1864 pub exprs: Vec<Expr>,
1865 pub having: Option<Expr>,
1866}
1867impl ToTokens for GroupBy {
1868 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1869 s.append(TK_GROUP, None)?;
1870 s.append(TK_BY, None)?;
1871 comma(&self.exprs, s)?;
1872 if let Some(ref having) = self.having {
1873 s.append(TK_HAVING, None)?;
1874 having.to_tokens(s)?;
1875 }
1876 Ok(())
1877 }
1878}
1879
1880#[derive(Clone, Debug, PartialEq, Eq)]
1882pub struct Id(pub String);
1883
1884impl Id {
1885 pub fn from_token(ty: YYCODETYPE, token: Token) -> Id {
1886 Id(from_token(ty, token))
1887 }
1888}
1889impl ToTokens for Id {
1890 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1891 double_quote(&self.0, s)
1892 }
1893}
1894
1895#[derive(Clone, Debug, PartialEq, Eq)]
1899pub struct Name(pub String); impl Name {
1902 pub fn from_token(ty: YYCODETYPE, token: Token) -> Name {
1903 Name(from_token(ty, token))
1904 }
1905}
1906impl ToTokens for Name {
1907 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1908 double_quote(&self.0, s)
1909 }
1910}
1911
1912impl Display for Name {
1913 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1914 self.to_fmt(f)
1915 }
1916}
1917
1918#[derive(Clone, Debug, PartialEq, Eq)]
1919pub struct QualifiedName {
1920 pub db_name: Option<Name>,
1921 pub name: Name,
1922 pub alias: Option<Name>, }
1924
1925impl QualifiedName {
1926 pub fn single(name: Name) -> Self {
1927 QualifiedName {
1928 db_name: None,
1929 name,
1930 alias: None,
1931 }
1932 }
1933 pub fn fullname(db_name: Name, name: Name) -> Self {
1934 QualifiedName {
1935 db_name: Some(db_name),
1936 name,
1937 alias: None,
1938 }
1939 }
1940 pub fn xfullname(db_name: Name, name: Name, alias: Name) -> Self {
1941 QualifiedName {
1942 db_name: Some(db_name),
1943 name,
1944 alias: Some(alias),
1945 }
1946 }
1947 pub fn alias(name: Name, alias: Name) -> Self {
1948 QualifiedName {
1949 db_name: None,
1950 name,
1951 alias: Some(alias),
1952 }
1953 }
1954}
1955impl ToTokens for QualifiedName {
1956 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1957 if let Some(ref db_name) = self.db_name {
1958 db_name.to_tokens(s)?;
1959 s.append(TK_DOT, None)?;
1960 }
1961 self.name.to_tokens(s)?;
1962 if let Some(ref alias) = self.alias {
1963 s.append(TK_AS, None)?;
1964 alias.to_tokens(s)?;
1965 }
1966 Ok(())
1967 }
1968}
1969
1970#[derive(Clone, Debug, PartialEq, Eq)]
1972pub enum AlterTableBody {
1973 RenameTo(Name),
1975 AddColumn(ColumnDefinition), RenameColumn { old: Name, new: Name },
1977 DropColumn(Name), AlterColumn { old: Name, cd: ColumnDefinition },
1979}
1980impl ToTokens for AlterTableBody {
1981 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1982 match self {
1983 AlterTableBody::RenameTo(name) => {
1984 s.append(TK_RENAME, None)?;
1985 s.append(TK_TO, None)?;
1986 name.to_tokens(s)
1987 }
1988 AlterTableBody::AddColumn(def) => {
1989 s.append(TK_ADD, None)?;
1990 s.append(TK_COLUMNKW, None)?;
1991 def.to_tokens(s)
1992 }
1993 AlterTableBody::RenameColumn { old, new } => {
1994 s.append(TK_RENAME, None)?;
1995 old.to_tokens(s)?;
1996 s.append(TK_TO, None)?;
1997 new.to_tokens(s)
1998 }
1999 AlterTableBody::DropColumn(name) => {
2000 s.append(TK_DROP, None)?;
2001 s.append(TK_COLUMNKW, None)?;
2002 name.to_tokens(s)
2003 }
2004 AlterTableBody::AlterColumn { old, cd } => {
2005 s.append(TK_ALTER, None)?;
2006 s.append(TK_COLUMNKW, None)?;
2007 old.to_tokens(s)?;
2008 s.append(TK_TO, None)?;
2009 cd.to_tokens(s)
2010 }
2011 }
2012 }
2013}
2014
2015#[derive(Clone, Debug, PartialEq, Eq)]
2018pub enum CreateTableBody {
2019 ColumnsAndConstraints {
2020 columns: Vec<ColumnDefinition>,
2021 constraints: Option<Vec<NamedTableConstraint>>,
2022 options: TableOptions,
2023 },
2024 AsSelect(Select),
2025}
2026
2027impl CreateTableBody {
2028 pub fn columns_and_constraints(
2029 columns: Vec<ColumnDefinition>,
2030 constraints: Option<Vec<NamedTableConstraint>>,
2031 options: TableOptions,
2032 ) -> Result<CreateTableBody, ParserError> {
2033 Ok(CreateTableBody::ColumnsAndConstraints {
2034 columns,
2035 constraints,
2036 options,
2037 })
2038 }
2039}
2040
2041impl ToTokens for CreateTableBody {
2042 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
2043 match self {
2044 CreateTableBody::ColumnsAndConstraints {
2045 columns,
2046 constraints,
2047 options,
2048 } => {
2049 s.append(TK_LP, None)?;
2050 comma(columns, s)?;
2051 if let Some(constraints) = constraints {
2052 s.append(TK_COMMA, None)?;
2053 comma(constraints, s)?;
2054 }
2055 s.append(TK_RP, None)?;
2056 if options.contains(TableOptions::WITHOUT_ROWID) {
2057 s.append(TK_WITHOUT, None)?;
2058 s.append(TK_ID, Some("ROWID"))?;
2059 } else if options.contains(TableOptions::RANDOM_ROWID) {
2060 s.append(TK_ID, Some("RANDOM"))?;
2061 s.append(TK_ID, Some("ROWID"))?;
2062 }
2063 if options.contains(TableOptions::STRICT) {
2064 s.append(TK_ID, Some("STRICT"))?;
2065 }
2066 Ok(())
2067 }
2068 CreateTableBody::AsSelect(select) => {
2069 s.append(TK_AS, None)?;
2070 select.to_tokens(s)
2071 }
2072 }
2073 }
2074}
2075
2076#[derive(Clone, Debug, PartialEq, Eq)]
2078pub struct ColumnDefinition {
2079 pub col_name: Name,
2080 pub col_type: Option<Type>,
2081 pub constraints: Vec<NamedColumnConstraint>,
2082}
2083impl ToTokens for ColumnDefinition {
2084 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
2085 self.col_name.to_tokens(s)?;
2086 if let Some(ref col_type) = self.col_type {
2087 col_type.to_tokens(s)?;
2088 }
2089 for constraint in self.constraints.iter() {
2090 constraint.to_tokens(s)?;
2091 }
2092 Ok(())
2093 }
2094}
2095impl ColumnDefinition {
2096 pub fn add_column(
2097 columns: &mut Vec<ColumnDefinition>,
2098 cd: ColumnDefinition,
2099 ) -> Result<(), ParserError> {
2100 if columns
2101 .iter()
2102 .any(|c| c.col_name.0.eq_ignore_ascii_case(&cd.col_name.0))
2103 {
2104 return Err(ParserError::Custom(format!(
2105 "duplicate column name: {}",
2106 cd.col_name
2107 )));
2108 }
2109 columns.push(cd);
2110 Ok(())
2111 }
2112}
2113
2114#[derive(Clone, Debug, PartialEq, Eq)]
2116pub struct NamedColumnConstraint {
2117 pub name: Option<Name>,
2118 pub constraint: ColumnConstraint,
2119}
2120impl ToTokens for NamedColumnConstraint {
2121 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
2122 if let Some(ref name) = self.name {
2123 s.append(TK_CONSTRAINT, None)?;
2124 name.to_tokens(s)?;
2125 }
2126 self.constraint.to_tokens(s)
2127 }
2128}
2129
2130#[derive(Clone, Debug, PartialEq, Eq)]
2132pub enum ColumnConstraint {
2133 PrimaryKey {
2134 order: Option<SortOrder>,
2135 conflict_clause: Option<ResolveType>,
2136 auto_increment: bool,
2137 },
2138 NotNull {
2139 nullable: bool,
2140 conflict_clause: Option<ResolveType>,
2141 },
2142 Unique(Option<ResolveType>),
2143 Check(Expr),
2144 Default(Expr),
2145 Defer(DeferSubclause), Collate {
2147 collation_name: Name, },
2149 ForeignKey {
2150 clause: ForeignKeyClause,
2151 deref_clause: Option<DeferSubclause>,
2152 },
2153 Generated {
2154 expr: Expr,
2155 typ: Option<Id>,
2156 },
2157}
2158impl ToTokens for ColumnConstraint {
2159 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
2160 match self {
2161 ColumnConstraint::PrimaryKey {
2162 order,
2163 conflict_clause,
2164 auto_increment,
2165 } => {
2166 s.append(TK_PRIMARY, None)?;
2167 s.append(TK_KEY, None)?;
2168 if let Some(order) = order {
2169 order.to_tokens(s)?;
2170 }
2171 if let Some(conflict_clause) = conflict_clause {
2172 s.append(TK_ON, None)?;
2173 s.append(TK_CONFLICT, None)?;
2174 conflict_clause.to_tokens(s)?;
2175 }
2176 if *auto_increment {
2177 s.append(TK_AUTOINCR, None)?;
2178 }
2179 Ok(())
2180 }
2181 ColumnConstraint::NotNull {
2182 nullable,
2183 conflict_clause,
2184 } => {
2185 if !nullable {
2186 s.append(TK_NOT, None)?;
2187 }
2188 s.append(TK_NULL, None)?;
2189 if let Some(conflict_clause) = conflict_clause {
2190 s.append(TK_ON, None)?;
2191 s.append(TK_CONFLICT, None)?;
2192 conflict_clause.to_tokens(s)?;
2193 }
2194 Ok(())
2195 }
2196 ColumnConstraint::Unique(conflict_clause) => {
2197 s.append(TK_UNIQUE, None)?;
2198 if let Some(conflict_clause) = conflict_clause {
2199 s.append(TK_ON, None)?;
2200 s.append(TK_CONFLICT, None)?;
2201 conflict_clause.to_tokens(s)?;
2202 }
2203 Ok(())
2204 }
2205 ColumnConstraint::Check(expr) => {
2206 s.append(TK_CHECK, None)?;
2207 s.append(TK_LP, None)?;
2208 expr.to_tokens(s)?;
2209 s.append(TK_RP, None)
2210 }
2211 ColumnConstraint::Default(expr) => {
2212 s.append(TK_DEFAULT, None)?;
2213 expr.to_tokens(s)
2214 }
2215 ColumnConstraint::Defer(deref_clause) => deref_clause.to_tokens(s),
2216 ColumnConstraint::Collate { collation_name } => {
2217 s.append(TK_COLLATE, None)?;
2218 collation_name.to_tokens(s)
2219 }
2220 ColumnConstraint::ForeignKey {
2221 clause,
2222 deref_clause,
2223 } => {
2224 s.append(TK_REFERENCES, None)?;
2225 clause.to_tokens(s)?;
2226 if let Some(deref_clause) = deref_clause {
2227 deref_clause.to_tokens(s)?;
2228 }
2229 Ok(())
2230 }
2231 ColumnConstraint::Generated { expr, typ } => {
2232 s.append(TK_AS, None)?;
2233 s.append(TK_LP, None)?;
2234 expr.to_tokens(s)?;
2235 s.append(TK_RP, None)?;
2236 if let Some(typ) = typ {
2237 typ.to_tokens(s)?;
2238 }
2239 Ok(())
2240 }
2241 }
2242 }
2243}
2244
2245#[derive(Clone, Debug, PartialEq, Eq)]
2247pub struct NamedTableConstraint {
2248 pub name: Option<Name>,
2249 pub constraint: TableConstraint,
2250}
2251impl ToTokens for NamedTableConstraint {
2252 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
2253 if let Some(ref name) = self.name {
2254 s.append(TK_CONSTRAINT, None)?;
2255 name.to_tokens(s)?;
2256 }
2257 self.constraint.to_tokens(s)
2258 }
2259}
2260
2261#[derive(Clone, Debug, PartialEq, Eq)]
2263pub enum TableConstraint {
2264 PrimaryKey {
2265 columns: Vec<SortedColumn>,
2266 auto_increment: bool,
2267 conflict_clause: Option<ResolveType>,
2268 },
2269 Unique {
2270 columns: Vec<SortedColumn>,
2271 conflict_clause: Option<ResolveType>,
2272 },
2273 Check(Expr),
2274 ForeignKey {
2275 columns: Vec<IndexedColumn>,
2276 clause: ForeignKeyClause,
2277 deref_clause: Option<DeferSubclause>,
2278 },
2279}
2280impl ToTokens for TableConstraint {
2281 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
2282 match self {
2283 TableConstraint::PrimaryKey {
2284 columns,
2285 auto_increment,
2286 conflict_clause,
2287 } => {
2288 s.append(TK_PRIMARY, None)?;
2289 s.append(TK_KEY, None)?;
2290 s.append(TK_LP, None)?;
2291 comma(columns, s)?;
2292 if *auto_increment {
2293 s.append(TK_AUTOINCR, None)?;
2294 }
2295 s.append(TK_RP, None)?;
2296 if let Some(conflict_clause) = conflict_clause {
2297 s.append(TK_ON, None)?;
2298 s.append(TK_CONFLICT, None)?;
2299 conflict_clause.to_tokens(s)?;
2300 }
2301 Ok(())
2302 }
2303 TableConstraint::Unique {
2304 columns,
2305 conflict_clause,
2306 } => {
2307 s.append(TK_UNIQUE, None)?;
2308 s.append(TK_LP, None)?;
2309 comma(columns, s)?;
2310 s.append(TK_RP, None)?;
2311 if let Some(conflict_clause) = conflict_clause {
2312 s.append(TK_ON, None)?;
2313 s.append(TK_CONFLICT, None)?;
2314 conflict_clause.to_tokens(s)?;
2315 }
2316 Ok(())
2317 }
2318 TableConstraint::Check(expr) => {
2319 s.append(TK_CHECK, None)?;
2320 s.append(TK_LP, None)?;
2321 expr.to_tokens(s)?;
2322 s.append(TK_RP, None)
2323 }
2324 TableConstraint::ForeignKey {
2325 columns,
2326 clause,
2327 deref_clause,
2328 } => {
2329 s.append(TK_FOREIGN, None)?;
2330 s.append(TK_KEY, None)?;
2331 s.append(TK_LP, None)?;
2332 comma(columns, s)?;
2333 s.append(TK_RP, None)?;
2334 s.append(TK_REFERENCES, None)?;
2335 clause.to_tokens(s)?;
2336 if let Some(deref_clause) = deref_clause {
2337 deref_clause.to_tokens(s)?;
2338 }
2339 Ok(())
2340 }
2341 }
2342 }
2343}
2344
2345bitflags::bitflags! {
2346 #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
2347 pub struct TableOptions: u8 {
2348 const NONE = 0;
2349 const WITHOUT_ROWID = 1;
2350 const STRICT = 2;
2351 const RANDOM_ROWID = 3;
2352 }
2353}
2354
2355#[derive(Copy, Clone, Debug, PartialEq, Eq)]
2356pub enum SortOrder {
2357 Asc,
2358 Desc,
2359}
2360impl ToTokens for SortOrder {
2361 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
2362 s.append(
2363 match self {
2364 SortOrder::Asc => TK_ASC,
2365 SortOrder::Desc => TK_DESC,
2366 },
2367 None,
2368 )
2369 }
2370}
2371
2372#[derive(Copy, Clone, Debug, PartialEq, Eq)]
2373pub enum NullsOrder {
2374 First,
2375 Last,
2376}
2377impl ToTokens for NullsOrder {
2378 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
2379 s.append(TK_NULLS, None)?;
2380 s.append(
2381 match self {
2382 NullsOrder::First => TK_FIRST,
2383 NullsOrder::Last => TK_LAST,
2384 },
2385 None,
2386 )
2387 }
2388}
2389
2390#[derive(Clone, Debug, PartialEq, Eq)]
2392pub struct ForeignKeyClause {
2393 pub tbl_name: Name,
2394 pub columns: Option<Vec<IndexedColumn>>,
2395 pub args: Vec<RefArg>,
2396}
2397impl ToTokens for ForeignKeyClause {
2398 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
2399 self.tbl_name.to_tokens(s)?;
2400 if let Some(ref columns) = self.columns {
2401 s.append(TK_LP, None)?;
2402 comma(columns, s)?;
2403 s.append(TK_RP, None)?;
2404 }
2405 for arg in self.args.iter() {
2406 arg.to_tokens(s)?;
2407 }
2408 Ok(())
2409 }
2410}
2411
2412#[derive(Clone, Debug, PartialEq, Eq)]
2413pub enum RefArg {
2414 OnDelete(RefAct),
2415 OnInsert(RefAct),
2416 OnUpdate(RefAct),
2417 Match(Name),
2418}
2419impl ToTokens for RefArg {
2420 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
2421 match self {
2422 RefArg::OnDelete(ref action) => {
2423 s.append(TK_ON, None)?;
2424 s.append(TK_DELETE, None)?;
2425 action.to_tokens(s)
2426 }
2427 RefArg::OnInsert(ref action) => {
2428 s.append(TK_ON, None)?;
2429 s.append(TK_INSERT, None)?;
2430 action.to_tokens(s)
2431 }
2432 RefArg::OnUpdate(ref action) => {
2433 s.append(TK_ON, None)?;
2434 s.append(TK_UPDATE, None)?;
2435 action.to_tokens(s)
2436 }
2437 RefArg::Match(ref name) => {
2438 s.append(TK_MATCH, None)?;
2439 name.to_tokens(s)
2440 }
2441 }
2442 }
2443}
2444
2445#[derive(Copy, Clone, Debug, PartialEq, Eq)]
2446pub enum RefAct {
2447 SetNull,
2448 SetDefault,
2449 Cascade,
2450 Restrict,
2451 NoAction,
2452}
2453impl ToTokens for RefAct {
2454 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
2455 match self {
2456 RefAct::SetNull => {
2457 s.append(TK_SET, None)?;
2458 s.append(TK_NULL, None)
2459 }
2460 RefAct::SetDefault => {
2461 s.append(TK_SET, None)?;
2462 s.append(TK_DEFAULT, None)
2463 }
2464 RefAct::Cascade => s.append(TK_CASCADE, None),
2465 RefAct::Restrict => s.append(TK_RESTRICT, None),
2466 RefAct::NoAction => {
2467 s.append(TK_NO, None)?;
2468 s.append(TK_ACTION, None)
2469 }
2470 }
2471 }
2472}
2473
2474#[derive(Clone, Debug, PartialEq, Eq)]
2475pub struct DeferSubclause {
2476 pub deferrable: bool,
2477 pub init_deferred: Option<InitDeferredPred>,
2478}
2479impl ToTokens for DeferSubclause {
2480 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
2481 if !self.deferrable {
2482 s.append(TK_NOT, None)?;
2483 }
2484 s.append(TK_DEFERRABLE, None)?;
2485 if let Some(init_deferred) = self.init_deferred {
2486 init_deferred.to_tokens(s)?;
2487 }
2488 Ok(())
2489 }
2490}
2491
2492#[derive(Copy, Clone, Debug, PartialEq, Eq)]
2493pub enum InitDeferredPred {
2494 InitiallyDeferred,
2495 InitiallyImmediate, }
2497impl ToTokens for InitDeferredPred {
2498 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
2499 s.append(TK_INITIALLY, None)?;
2500 s.append(
2501 match self {
2502 InitDeferredPred::InitiallyDeferred => TK_DEFERRED,
2503 InitDeferredPred::InitiallyImmediate => TK_IMMEDIATE,
2504 },
2505 None,
2506 )
2507 }
2508}
2509
2510#[derive(Clone, Debug, PartialEq, Eq)]
2512pub struct IndexedColumn {
2513 pub col_name: Name,
2514 pub collation_name: Option<Name>, pub order: Option<SortOrder>,
2516}
2517impl ToTokens for IndexedColumn {
2518 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
2519 self.col_name.to_tokens(s)?;
2520 if let Some(ref collation_name) = self.collation_name {
2521 s.append(TK_COLLATE, None)?;
2522 collation_name.to_tokens(s)?;
2523 }
2524 if let Some(order) = self.order {
2525 order.to_tokens(s)?;
2526 }
2527 Ok(())
2528 }
2529}
2530
2531#[derive(Clone, Debug, PartialEq, Eq)]
2532pub enum Indexed {
2533 IndexedBy(Name),
2535 NotIndexed,
2536}
2537impl ToTokens for Indexed {
2538 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
2539 match self {
2540 Indexed::IndexedBy(ref name) => {
2541 s.append(TK_INDEXED, None)?;
2542 s.append(TK_BY, None)?;
2543 name.to_tokens(s)
2544 }
2545 Indexed::NotIndexed => {
2546 s.append(TK_NOT, None)?;
2547 s.append(TK_INDEXED, None)
2548 }
2549 }
2550 }
2551}
2552
2553#[derive(Clone, Debug, PartialEq, Eq)]
2554pub struct SortedColumn {
2555 pub expr: Expr,
2556 pub order: Option<SortOrder>,
2557 pub nulls: Option<NullsOrder>,
2558}
2559impl ToTokens for SortedColumn {
2560 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
2561 self.expr.to_tokens(s)?;
2562 if let Some(ref order) = self.order {
2563 order.to_tokens(s)?;
2564 }
2565 if let Some(ref nulls) = self.nulls {
2566 nulls.to_tokens(s)?;
2567 }
2568 Ok(())
2569 }
2570}
2571
2572#[derive(Clone, Debug, PartialEq, Eq)]
2573pub struct Limit {
2574 pub expr: Expr,
2575 pub offset: Option<Expr>, }
2577impl ToTokens for Limit {
2578 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
2579 s.append(TK_LIMIT, None)?;
2580 self.expr.to_tokens(s)?;
2581 if let Some(ref offset) = self.offset {
2582 s.append(TK_OFFSET, None)?;
2583 offset.to_tokens(s)?;
2584 }
2585 Ok(())
2586 }
2587}
2588
2589#[derive(Clone, Debug, PartialEq, Eq)]
2592pub enum InsertBody {
2593 Select(Select, Option<Upsert>),
2594 DefaultValues,
2595}
2596impl ToTokens for InsertBody {
2597 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
2598 match self {
2599 InsertBody::Select(select, upsert) => {
2600 select.to_tokens(s)?;
2601 if let Some(upsert) = upsert {
2602 upsert.to_tokens(s)?;
2603 }
2604 Ok(())
2605 }
2606 InsertBody::DefaultValues => {
2607 s.append(TK_DEFAULT, None)?;
2608 s.append(TK_VALUES, None)
2609 }
2610 }
2611 }
2612}
2613
2614#[derive(Clone, Debug, PartialEq, Eq)]
2615pub struct Set {
2616 pub col_names: Vec<Name>,
2617 pub expr: Expr,
2618}
2619impl ToTokens for Set {
2620 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
2621 if self.col_names.len() == 1 {
2622 comma(&self.col_names, s)?;
2623 } else {
2624 s.append(TK_LP, None)?;
2625 comma(&self.col_names, s)?;
2626 s.append(TK_RP, None)?;
2627 }
2628 s.append(TK_EQ, None)?;
2629 self.expr.to_tokens(s)
2630 }
2631}
2632
2633#[derive(Clone, Debug, PartialEq, Eq)]
2635pub enum PragmaBody {
2636 Equals(PragmaValue),
2637 Call(PragmaValue),
2638}
2639impl ToTokens for PragmaBody {
2640 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
2641 match self {
2642 PragmaBody::Equals(value) => {
2643 s.append(TK_EQ, None)?;
2644 value.to_tokens(s)
2645 }
2646 PragmaBody::Call(value) => {
2647 s.append(TK_LP, None)?;
2648 value.to_tokens(s)?;
2649 s.append(TK_RP, None)
2650 }
2651 }
2652 }
2653}
2654
2655pub type PragmaValue = Expr; #[derive(Copy, Clone, Debug, PartialEq, Eq)]
2659pub enum TriggerTime {
2660 Before, After,
2662 InsteadOf,
2663}
2664impl ToTokens for TriggerTime {
2665 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
2666 match self {
2667 TriggerTime::Before => s.append(TK_BEFORE, None),
2668 TriggerTime::After => s.append(TK_AFTER, None),
2669 TriggerTime::InsteadOf => {
2670 s.append(TK_INSTEAD, None)?;
2671 s.append(TK_OF, None)
2672 }
2673 }
2674 }
2675}
2676
2677#[derive(Clone, Debug, PartialEq, Eq)]
2678pub enum TriggerEvent {
2679 Delete,
2680 Insert,
2681 Update,
2682 UpdateOf(Vec<Name>),
2684}
2685impl ToTokens for TriggerEvent {
2686 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
2687 match self {
2688 TriggerEvent::Delete => s.append(TK_DELETE, None),
2689 TriggerEvent::Insert => s.append(TK_INSERT, None),
2690 TriggerEvent::Update => s.append(TK_UPDATE, None),
2691 TriggerEvent::UpdateOf(ref col_names) => {
2692 s.append(TK_UPDATE, None)?;
2693 s.append(TK_OF, None)?;
2694 comma(col_names, s)
2695 }
2696 }
2697 }
2698}
2699
2700#[derive(Clone, Debug, PartialEq, Eq)]
2703pub enum TriggerCmd {
2704 Update {
2705 or_conflict: Option<ResolveType>,
2706 tbl_name: Name,
2707 sets: Vec<Set>,
2708 from: Option<FromClause>,
2709 where_clause: Option<Expr>,
2710 },
2711 Insert {
2712 or_conflict: Option<ResolveType>,
2713 tbl_name: Name,
2714 col_names: Option<Vec<Name>>,
2715 select: Select,
2716 upsert: Option<Upsert>,
2717 returning: Option<Vec<ResultColumn>>,
2718 },
2719 Delete {
2720 tbl_name: Name,
2721 where_clause: Option<Expr>,
2722 },
2723 Select(Select),
2724}
2725impl ToTokens for TriggerCmd {
2726 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
2727 match self {
2728 TriggerCmd::Update {
2729 or_conflict,
2730 tbl_name,
2731 sets,
2732 from,
2733 where_clause,
2734 } => {
2735 s.append(TK_UPDATE, None)?;
2736 if let Some(or_conflict) = or_conflict {
2737 s.append(TK_OR, None)?;
2738 or_conflict.to_tokens(s)?;
2739 }
2740 tbl_name.to_tokens(s)?;
2741 s.append(TK_SET, None)?;
2742 comma(sets, s)?;
2743 if let Some(from) = from {
2744 s.append(TK_FROM, None)?;
2745 from.to_tokens(s)?;
2746 }
2747 if let Some(where_clause) = where_clause {
2748 s.append(TK_WHERE, None)?;
2749 where_clause.to_tokens(s)?;
2750 }
2751 Ok(())
2752 }
2753 TriggerCmd::Insert {
2754 or_conflict,
2755 tbl_name,
2756 col_names,
2757 select,
2758 upsert,
2759 returning,
2760 } => {
2761 if let Some(ResolveType::Replace) = or_conflict {
2762 s.append(TK_REPLACE, None)?;
2763 } else {
2764 s.append(TK_INSERT, None)?;
2765 if let Some(or_conflict) = or_conflict {
2766 s.append(TK_OR, None)?;
2767 or_conflict.to_tokens(s)?;
2768 }
2769 }
2770 s.append(TK_INTO, None)?;
2771 tbl_name.to_tokens(s)?;
2772 if let Some(col_names) = col_names {
2773 s.append(TK_LP, None)?;
2774 comma(col_names, s)?;
2775 s.append(TK_RP, None)?;
2776 }
2777 select.to_tokens(s)?;
2778 if let Some(upsert) = upsert {
2779 upsert.to_tokens(s)?;
2780 }
2781 if let Some(returning) = returning {
2782 s.append(TK_RETURNING, None)?;
2783 comma(returning, s)?;
2784 }
2785 Ok(())
2786 }
2787 TriggerCmd::Delete {
2788 tbl_name,
2789 where_clause,
2790 } => {
2791 s.append(TK_DELETE, None)?;
2792 s.append(TK_FROM, None)?;
2793 tbl_name.to_tokens(s)?;
2794 if let Some(where_clause) = where_clause {
2795 s.append(TK_WHERE, None)?;
2796 where_clause.to_tokens(s)?;
2797 }
2798 Ok(())
2799 }
2800 TriggerCmd::Select(select) => select.to_tokens(s),
2801 }
2802 }
2803}
2804
2805#[derive(Copy, Clone, Debug, PartialEq, Eq)]
2806pub enum ResolveType {
2807 Rollback,
2808 Abort, Fail,
2810 Ignore,
2811 Replace,
2812}
2813impl ToTokens for ResolveType {
2814 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
2815 s.append(
2816 match self {
2817 ResolveType::Rollback => TK_ROLLBACK,
2818 ResolveType::Abort => TK_ABORT,
2819 ResolveType::Fail => TK_FAIL,
2820 ResolveType::Ignore => TK_IGNORE,
2821 ResolveType::Replace => TK_REPLACE,
2822 },
2823 None,
2824 )
2825 }
2826}
2827
2828#[derive(Clone, Debug, PartialEq, Eq)]
2831pub struct With {
2832 pub recursive: bool,
2833 pub ctes: Vec<CommonTableExpr>,
2834}
2835impl ToTokens for With {
2836 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
2837 s.append(TK_WITH, None)?;
2838 if self.recursive {
2839 s.append(TK_RECURSIVE, None)?;
2840 }
2841 comma(&self.ctes, s)
2842 }
2843}
2844
2845#[derive(Clone, Debug, PartialEq, Eq)]
2846pub enum Materialized {
2847 Any,
2848 Yes,
2849 No,
2850}
2851
2852#[derive(Clone, Debug, PartialEq, Eq)]
2854pub struct CommonTableExpr {
2855 pub tbl_name: Name,
2856 pub columns: Option<Vec<IndexedColumn>>,
2857 pub materialized: Materialized,
2858 pub select: Select,
2859}
2860
2861impl ToTokens for CommonTableExpr {
2862 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
2863 self.tbl_name.to_tokens(s)?;
2864 if let Some(ref columns) = self.columns {
2865 s.append(TK_LP, None)?;
2866 comma(columns, s)?;
2867 s.append(TK_RP, None)?;
2868 }
2869 s.append(TK_AS, None)?;
2870 match self.materialized {
2871 Materialized::Any => {}
2872 Materialized::Yes => {
2873 s.append(TK_MATERIALIZED, None)?;
2874 }
2875 Materialized::No => {
2876 s.append(TK_NOT, None)?;
2877 s.append(TK_MATERIALIZED, None)?;
2878 }
2879 };
2880 s.append(TK_LP, None)?;
2881 self.select.to_tokens(s)?;
2882 s.append(TK_RP, None)
2883 }
2884}
2885
2886impl CommonTableExpr {
2887 pub fn add_cte(
2888 ctes: &mut Vec<CommonTableExpr>,
2889 cte: CommonTableExpr,
2890 ) -> Result<(), ParserError> {
2891 if ctes
2892 .iter()
2893 .any(|c| c.tbl_name.0.eq_ignore_ascii_case(&cte.tbl_name.0))
2894 {
2895 return Err(ParserError::Custom(format!(
2896 "duplicate WITH table name: {}",
2897 cte.tbl_name
2898 )));
2899 }
2900 ctes.push(cte);
2901 Ok(())
2902 }
2903}
2904
2905#[derive(Clone, Debug, PartialEq, Eq)]
2907pub struct Type {
2908 pub name: String, pub size: Option<TypeSize>,
2910}
2911impl ToTokens for Type {
2912 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
2913 match self.size {
2914 None => s.append(TK_ID, Some(&self.name)),
2915 Some(ref size) => {
2916 s.append(TK_ID, Some(&self.name))?; s.append(TK_LP, None)?;
2918 size.to_tokens(s)?;
2919 s.append(TK_RP, None)
2920 }
2921 }
2922 }
2923}
2924
2925#[derive(Clone, Debug, PartialEq, Eq)]
2927pub enum TypeSize {
2928 MaxSize(Box<Expr>),
2929 TypeSize(Box<Expr>, Box<Expr>),
2930}
2931
2932impl ToTokens for TypeSize {
2933 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
2934 match self {
2935 TypeSize::MaxSize(size) => size.to_tokens(s),
2936 TypeSize::TypeSize(size1, size2) => {
2937 size1.to_tokens(s)?;
2938 s.append(TK_COMMA, None)?;
2939 size2.to_tokens(s)
2940 }
2941 }
2942 }
2943}
2944
2945#[derive(Copy, Clone, Debug, PartialEq, Eq)]
2946pub enum TransactionType {
2947 Deferred, Immediate,
2949 Exclusive,
2950 ReadOnly,
2951}
2952impl ToTokens for TransactionType {
2953 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
2954 s.append(
2955 match self {
2956 TransactionType::Deferred => TK_DEFERRED,
2957 TransactionType::Immediate => TK_IMMEDIATE,
2958 TransactionType::Exclusive => TK_EXCLUSIVE,
2959 TransactionType::ReadOnly => TK_READONLY,
2960 },
2961 None,
2962 )
2963 }
2964}
2965
2966#[derive(Clone, Debug, PartialEq, Eq)]
2969pub struct Upsert {
2970 pub index: Option<UpsertIndex>,
2971 pub do_clause: UpsertDo,
2972 pub next: Option<Box<Upsert>>,
2973}
2974
2975impl ToTokens for Upsert {
2976 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
2977 s.append(TK_ON, None)?;
2978 s.append(TK_CONFLICT, None)?;
2979 if let Some(ref index) = self.index {
2980 index.to_tokens(s)?;
2981 }
2982 self.do_clause.to_tokens(s)?;
2983 if let Some(ref next) = self.next {
2984 next.to_tokens(s)?;
2985 }
2986 Ok(())
2987 }
2988}
2989
2990#[derive(Clone, Debug, PartialEq, Eq)]
2991pub struct UpsertIndex {
2992 pub targets: Vec<SortedColumn>,
2993 pub where_clause: Option<Expr>,
2994}
2995
2996impl ToTokens for UpsertIndex {
2997 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
2998 s.append(TK_LP, None)?;
2999 comma(&self.targets, s)?;
3000 s.append(TK_RP, None)?;
3001 if let Some(ref where_clause) = self.where_clause {
3002 s.append(TK_WHERE, None)?;
3003 where_clause.to_tokens(s)?;
3004 }
3005 Ok(())
3006 }
3007}
3008
3009#[derive(Clone, Debug, PartialEq, Eq)]
3010pub enum UpsertDo {
3011 Set {
3012 sets: Vec<Set>,
3013 where_clause: Option<Expr>,
3014 },
3015 Nothing,
3016}
3017
3018impl ToTokens for UpsertDo {
3019 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
3020 match self {
3021 UpsertDo::Set { sets, where_clause } => {
3022 s.append(TK_DO, None)?;
3023 s.append(TK_UPDATE, None)?;
3024 s.append(TK_SET, None)?;
3025 comma(sets, s)?;
3026 if let Some(where_clause) = where_clause {
3027 s.append(TK_WHERE, None)?;
3028 where_clause.to_tokens(s)?;
3029 }
3030 Ok(())
3031 }
3032 UpsertDo::Nothing => {
3033 s.append(TK_DO, None)?;
3034 s.append(TK_NOTHING, None)
3035 }
3036 }
3037 }
3038}
3039
3040#[derive(Clone, Debug, PartialEq, Eq)]
3041pub struct FunctionTail {
3042 pub filter_clause: Option<Box<Expr>>,
3043 pub over_clause: Option<Box<Over>>,
3044}
3045impl ToTokens for FunctionTail {
3046 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
3047 if let Some(ref filter_clause) = self.filter_clause {
3048 s.append(TK_FILTER, None)?;
3049 s.append(TK_LP, None)?;
3050 s.append(TK_WHERE, None)?;
3051 filter_clause.to_tokens(s)?;
3052 s.append(TK_RP, None)?;
3053 }
3054 if let Some(ref over_clause) = self.over_clause {
3055 s.append(TK_OVER, None)?;
3056 over_clause.to_tokens(s)?;
3057 }
3058 Ok(())
3059 }
3060}
3061
3062#[derive(Clone, Debug, PartialEq, Eq)]
3064pub enum Over {
3065 Window(Window),
3066 Name(Name),
3067}
3068
3069impl ToTokens for Over {
3070 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
3071 match self {
3072 Over::Window(ref window) => window.to_tokens(s),
3073 Over::Name(ref name) => name.to_tokens(s),
3074 }
3075 }
3076}
3077
3078#[derive(Clone, Debug, PartialEq, Eq)]
3079pub struct WindowDef {
3080 pub name: Name,
3081 pub window: Window,
3082}
3083impl ToTokens for WindowDef {
3084 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
3085 self.name.to_tokens(s)?;
3086 s.append(TK_AS, None)?;
3087 self.window.to_tokens(s)
3088 }
3089}
3090
3091#[derive(Clone, Debug, PartialEq, Eq)]
3093pub struct Window {
3094 pub base: Option<Name>,
3095 pub partition_by: Option<Vec<Expr>>,
3096 pub order_by: Option<Vec<SortedColumn>>,
3097 pub frame_clause: Option<FrameClause>,
3098}
3099
3100impl ToTokens for Window {
3101 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
3102 s.append(TK_LP, None)?;
3103 if let Some(ref base) = self.base {
3104 base.to_tokens(s)?;
3105 }
3106 if let Some(ref partition_by) = self.partition_by {
3107 s.append(TK_PARTITION, None)?;
3108 s.append(TK_BY, None)?;
3109 comma(partition_by, s)?;
3110 }
3111 if let Some(ref order_by) = self.order_by {
3112 s.append(TK_ORDER, None)?;
3113 s.append(TK_BY, None)?;
3114 comma(order_by, s)?;
3115 }
3116 if let Some(ref frame_clause) = self.frame_clause {
3117 frame_clause.to_tokens(s)?;
3118 }
3119 s.append(TK_RP, None)
3120 }
3121}
3122
3123#[derive(Clone, Debug, PartialEq, Eq)]
3125pub struct FrameClause {
3126 pub mode: FrameMode,
3127 pub start: FrameBound,
3128 pub end: Option<FrameBound>,
3129 pub exclude: Option<FrameExclude>,
3130}
3131
3132impl ToTokens for FrameClause {
3133 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
3134 self.mode.to_tokens(s)?;
3135 if let Some(ref end) = self.end {
3136 s.append(TK_BETWEEN, None)?;
3137 self.start.to_tokens(s)?;
3138 s.append(TK_AND, None)?;
3139 end.to_tokens(s)?;
3140 } else {
3141 self.start.to_tokens(s)?;
3142 }
3143 if let Some(ref exclude) = self.exclude {
3144 s.append(TK_EXCLUDE, None)?;
3145 exclude.to_tokens(s)?;
3146 }
3147 Ok(())
3148 }
3149}
3150
3151#[derive(Copy, Clone, Debug, PartialEq, Eq)]
3152pub enum FrameMode {
3153 Groups,
3154 Range,
3155 Rows,
3156}
3157
3158impl ToTokens for FrameMode {
3159 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
3160 s.append(
3161 match self {
3162 FrameMode::Groups => TK_GROUPS,
3163 FrameMode::Range => TK_RANGE,
3164 FrameMode::Rows => TK_ROWS,
3165 },
3166 None,
3167 )
3168 }
3169}
3170
3171#[derive(Clone, Debug, PartialEq, Eq)]
3172pub enum FrameBound {
3173 CurrentRow,
3174 Following(Expr),
3175 Preceding(Expr),
3176 UnboundedFollowing,
3177 UnboundedPreceding,
3178}
3179
3180impl ToTokens for FrameBound {
3181 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
3182 match self {
3183 FrameBound::CurrentRow => {
3184 s.append(TK_CURRENT, None)?;
3185 s.append(TK_ROW, None)
3186 }
3187 FrameBound::Following(value) => {
3188 value.to_tokens(s)?;
3189 s.append(TK_FOLLOWING, None)
3190 }
3191 FrameBound::Preceding(value) => {
3192 value.to_tokens(s)?;
3193 s.append(TK_PRECEDING, None)
3194 }
3195 FrameBound::UnboundedFollowing => {
3196 s.append(TK_UNBOUNDED, None)?;
3197 s.append(TK_FOLLOWING, None)
3198 }
3199 FrameBound::UnboundedPreceding => {
3200 s.append(TK_UNBOUNDED, None)?;
3201 s.append(TK_PRECEDING, None)
3202 }
3203 }
3204 }
3205}
3206
3207#[derive(Clone, Debug, PartialEq, Eq)]
3208pub enum FrameExclude {
3209 NoOthers,
3210 CurrentRow,
3211 Group,
3212 Ties,
3213}
3214
3215impl ToTokens for FrameExclude {
3216 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
3217 match self {
3218 FrameExclude::NoOthers => {
3219 s.append(TK_NO, None)?;
3220 s.append(TK_OTHERS, None)
3221 }
3222 FrameExclude::CurrentRow => {
3223 s.append(TK_CURRENT, None)?;
3224 s.append(TK_ROW, None)
3225 }
3226 FrameExclude::Group => s.append(TK_GROUP, None),
3227 FrameExclude::Ties => s.append(TK_TIES, None),
3228 }
3229 }
3230}
3231
3232fn comma<I, S: TokenStream>(items: I, s: &mut S) -> Result<(), S::Error>
3233where
3234 I: IntoIterator,
3235 I::Item: ToTokens,
3236{
3237 let iter = items.into_iter();
3238 for (i, item) in iter.enumerate() {
3239 if i != 0 {
3240 s.append(TK_COMMA, None)?;
3241 }
3242 item.to_tokens(s)?;
3243 }
3244 Ok(())
3245}
3246
3247fn double_quote<S: TokenStream>(name: &str, s: &mut S) -> Result<(), S::Error> {
3249 if name.is_empty() {
3250 return s.append(TK_ID, Some("\"\""));
3251 }
3252 if is_identifier(name) {
3253 return s.append(TK_ID, Some(name));
3260 }
3261 s.append(TK_ID, Some(name))
3270}