1use std::fmt::{self, Display};
16
17use serde::Serialize;
18use sqlparser_derive::{Visit, VisitMut};
19
20use crate::ast::{Expr, Ident, ObjectName};
21
22#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
24pub enum ShowKind {
25 All,
26 Like(Ident),
27 Where(Expr),
28}
29
30impl Display for ShowKind {
31 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
32 match self {
33 ShowKind::All => write!(f, ""),
35 ShowKind::Like(ident) => write!(f, "LIKE {ident}"),
36 ShowKind::Where(expr) => write!(f, "WHERE {expr}"),
37 }
38 }
39}
40
41macro_rules! format_kind {
42 ($self: expr, $f: expr) => {
43 if $self.kind != ShowKind::All {
44 write!($f, " {}", &$self.kind)?;
45 }
46 };
47}
48
49#[cfg(feature = "enterprise")]
50pub mod trigger;
51
52#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
54pub struct ShowDatabases {
55 pub kind: ShowKind,
56 pub full: bool,
57}
58
59#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
61pub struct ShowColumns {
62 pub kind: ShowKind,
63 pub table: String,
64 pub database: Option<String>,
65 pub full: bool,
66}
67
68impl Display for ShowColumns {
69 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
70 write!(f, "SHOW ")?;
71 if self.full {
72 write!(f, "FULL ")?;
73 }
74 write!(f, "COLUMNS IN {}", &self.table)?;
75 if let Some(database) = &self.database {
76 write!(f, " IN {database}")?;
77 }
78 format_kind!(self, f);
79 Ok(())
80 }
81}
82
83#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
85pub struct ShowIndex {
86 pub kind: ShowKind,
87 pub table: String,
88 pub database: Option<String>,
89}
90
91impl Display for ShowIndex {
92 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
93 write!(f, "SHOW INDEX IN {}", &self.table)?;
94 if let Some(database) = &self.database {
95 write!(f, " IN {database}")?;
96 }
97 format_kind!(self, f);
98
99 Ok(())
100 }
101}
102
103#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
105pub struct ShowRegion {
106 pub kind: ShowKind,
107 pub table: String,
108 pub database: Option<String>,
109}
110
111impl Display for ShowRegion {
112 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
113 write!(f, "SHOW REGION IN {}", &self.table)?;
114 if let Some(database) = &self.database {
115 write!(f, " IN {database}")?;
116 }
117 format_kind!(self, f);
118 Ok(())
119 }
120}
121
122impl ShowDatabases {
123 pub fn new(kind: ShowKind, full: bool) -> Self {
125 ShowDatabases { kind, full }
126 }
127}
128
129impl Display for ShowDatabases {
130 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
131 if self.full {
132 write!(f, "SHOW FULL DATABASES")?;
133 } else {
134 write!(f, "SHOW DATABASES")?;
135 }
136
137 format_kind!(self, f);
138
139 Ok(())
140 }
141}
142
143#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
145pub struct ShowTables {
146 pub kind: ShowKind,
147 pub database: Option<String>,
148 pub full: bool,
149}
150
151impl Display for ShowTables {
152 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
153 write!(f, "SHOW ")?;
154 if self.full {
155 write!(f, "FULL ")?;
156 }
157 write!(f, "TABLES")?;
158 if let Some(database) = &self.database {
159 write!(f, " IN {database}")?;
160 }
161 format_kind!(self, f);
162
163 Ok(())
164 }
165}
166
167#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
169pub struct ShowTableStatus {
170 pub kind: ShowKind,
171 pub database: Option<String>,
172}
173
174impl Display for ShowTableStatus {
175 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
176 write!(f, "SHOW TABLE STATUS")?;
177 if let Some(database) = &self.database {
178 write!(f, " IN {database}")?;
179 }
180
181 format_kind!(self, f);
182
183 Ok(())
184 }
185}
186
187#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
189pub struct ShowCreateDatabase {
190 pub database_name: ObjectName,
191}
192
193impl Display for ShowCreateDatabase {
194 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
195 let database_name = &self.database_name;
196 write!(f, r#"SHOW CREATE DATABASE {database_name}"#)
197 }
198}
199
200#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
202pub struct ShowCreateTable {
203 pub table_name: ObjectName,
204 pub variant: ShowCreateTableVariant,
205}
206
207#[derive(Default, Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
209pub enum ShowCreateTableVariant {
210 #[default]
211 Original,
212 PostgresForeignTable,
213}
214
215impl Display for ShowCreateTable {
216 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
217 let table_name = &self.table_name;
218 write!(f, r#"SHOW CREATE TABLE {table_name}"#)?;
219 if let ShowCreateTableVariant::PostgresForeignTable = self.variant {
220 write!(f, " FOR POSTGRES_FOREIGN_TABLE")?;
221 }
222
223 Ok(())
224 }
225}
226
227#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
229pub struct ShowCreateFlow {
230 pub flow_name: ObjectName,
231}
232
233impl Display for ShowCreateFlow {
234 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
235 let flow_name = &self.flow_name;
236 write!(f, "SHOW CREATE FLOW {flow_name}")
237 }
238}
239
240#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
242pub struct ShowFlows {
243 pub kind: ShowKind,
244 pub database: Option<String>,
245}
246
247impl Display for ShowFlows {
248 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
249 write!(f, "SHOW FLOWS")?;
250 if let Some(database) = &self.database {
251 write!(f, " IN {database}")?;
252 }
253 format_kind!(self, f);
254
255 Ok(())
256 }
257}
258
259#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
261pub struct ShowCreateView {
262 pub view_name: ObjectName,
263}
264
265impl Display for ShowCreateView {
266 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
267 let view_name = &self.view_name;
268 write!(f, "SHOW CREATE VIEW {view_name}")
269 }
270}
271
272#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
274pub struct ShowViews {
275 pub kind: ShowKind,
276 pub database: Option<String>,
277}
278
279impl Display for ShowViews {
280 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
281 write!(f, "SHOW VIEWS")?;
282 if let Some(database) = &self.database {
283 write!(f, " IN {database}")?;
284 }
285 format_kind!(self, f);
286
287 Ok(())
288 }
289}
290
291#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
293pub struct ShowVariables {
294 pub variable: ObjectName,
295}
296
297impl Display for ShowVariables {
298 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
299 let variable = &self.variable;
300 write!(f, r#"SHOW VARIABLES {variable}"#)
301 }
302}
303
304#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
306pub struct ShowStatus {}
307
308impl Display for ShowStatus {
309 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
310 write!(f, "SHOW STATUS")
311 }
312}
313
314#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
316pub struct ShowSearchPath {}
317
318impl Display for ShowSearchPath {
319 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
320 write!(f, "SHOW SEARCH_PATH")
321 }
322}
323
324#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
326pub struct ShowProcessList {
327 pub full: bool,
328}
329impl Display for ShowProcessList {
330 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
331 if self.full {
332 write!(f, "SHOW FULL PROCESSLIST")?;
333 } else {
334 write!(f, "SHOW PROCESSLIST")?;
335 }
336
337 Ok(())
338 }
339}
340
341#[cfg(test)]
342mod tests {
343 use std::assert_matches::assert_matches;
344
345 use sqlparser::ast::UnaryOperator;
346
347 use super::*;
348 use crate::dialect::GreptimeDbDialect;
349 use crate::parser::{ParseOptions, ParserContext};
350 use crate::statements::statement::Statement;
351
352 #[test]
353 fn test_kind_display() {
354 assert_eq!("", format!("{}", ShowKind::All));
355 assert_eq!(
356 "LIKE test",
357 format!("{}", ShowKind::Like(Ident::new("test")),)
358 );
359 assert_eq!(
360 "WHERE NOT a",
361 format!(
362 "{}",
363 ShowKind::Where(Expr::UnaryOp {
364 op: UnaryOperator::Not,
365 expr: Box::new(Expr::Identifier(Ident::new("a"))),
366 })
367 )
368 );
369 }
370
371 #[test]
372 pub fn test_show_database() {
373 let sql = "SHOW DATABASES";
374 let stmts =
375 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
376 .unwrap();
377 assert_eq!(1, stmts.len());
378 assert_matches!(&stmts[0], Statement::ShowDatabases { .. });
379 match &stmts[0] {
380 Statement::ShowDatabases(show) => {
381 assert_eq!(ShowKind::All, show.kind);
382 }
383 _ => {
384 unreachable!();
385 }
386 }
387 }
388
389 #[test]
390 pub fn test_show_create_table() {
391 let sql = "SHOW CREATE TABLE test";
392 let stmts: Vec<Statement> =
393 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
394 .unwrap();
395 assert_eq!(1, stmts.len());
396 assert_matches!(&stmts[0], Statement::ShowCreateTable { .. });
397 match &stmts[0] {
398 Statement::ShowCreateTable(show) => {
399 let table_name = show.table_name.to_string();
400 assert_eq!(table_name, "test");
401 assert_eq!(show.variant, ShowCreateTableVariant::Original);
402 }
403 _ => {
404 unreachable!();
405 }
406 }
407
408 let sql = "SHOW CREATE TABLE test FOR POSTGRES_FOREIGN_TABLE";
409 let stmts: Vec<Statement> =
410 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
411 .unwrap();
412 assert_eq!(1, stmts.len());
413 assert_matches!(&stmts[0], Statement::ShowCreateTable { .. });
414 match &stmts[0] {
415 Statement::ShowCreateTable(show) => {
416 let table_name = show.table_name.to_string();
417 assert_eq!(table_name, "test");
418 assert_eq!(show.variant, ShowCreateTableVariant::PostgresForeignTable);
419 }
420 _ => {
421 unreachable!();
422 }
423 }
424 }
425
426 #[test]
427 pub fn test_show_create_missing_table_name() {
428 let sql = "SHOW CREATE TABLE";
429 assert!(
430 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
431 .is_err()
432 );
433 }
434
435 #[test]
436 pub fn test_show_create_unknown_for() {
437 let sql = "SHOW CREATE TABLE t FOR UNKNOWN";
438 assert!(
439 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
440 .is_err()
441 );
442 }
443
444 #[test]
445 pub fn test_show_create_flow() {
446 let sql = "SHOW CREATE FLOW test";
447 let stmts: Vec<Statement> =
448 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
449 .unwrap();
450 assert_eq!(1, stmts.len());
451 assert_matches!(&stmts[0], Statement::ShowCreateFlow { .. });
452 match &stmts[0] {
453 Statement::ShowCreateFlow(show) => {
454 let flow_name = show.flow_name.to_string();
455 assert_eq!(flow_name, "test");
456 }
457 _ => {
458 unreachable!();
459 }
460 }
461 }
462 #[test]
463 pub fn test_show_create_missing_flow() {
464 let sql = "SHOW CREATE FLOW";
465 assert!(
466 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
467 .is_err()
468 );
469 }
470
471 #[test]
472 fn test_display_show_variables() {
473 let sql = r"show variables v1;";
474 let stmts: Vec<Statement> =
475 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
476 .unwrap();
477 assert_eq!(1, stmts.len());
478 assert_matches!(&stmts[0], Statement::ShowVariables { .. });
479 match &stmts[0] {
480 Statement::ShowVariables(show) => {
481 let new_sql = format!("\n{}", show);
482 assert_eq!(
483 r#"
484SHOW VARIABLES v1"#,
485 &new_sql
486 );
487 }
488 _ => {
489 unreachable!();
490 }
491 }
492 }
493
494 #[test]
495 fn test_display_show_create_table() {
496 let sql = r"show create table monitor;";
497 let stmts: Vec<Statement> =
498 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
499 .unwrap();
500 assert_eq!(1, stmts.len());
501 assert_matches!(&stmts[0], Statement::ShowCreateTable { .. });
502 match &stmts[0] {
503 Statement::ShowCreateTable(show) => {
504 let new_sql = format!("\n{}", show);
505 assert_eq!(
506 r#"
507SHOW CREATE TABLE monitor"#,
508 &new_sql
509 );
510 }
511 _ => {
512 unreachable!();
513 }
514 }
515 }
516
517 #[test]
518 fn test_display_show_index() {
519 let sql = r"show index from t1 from d1;";
520 let stmts: Vec<Statement> =
521 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
522 .unwrap();
523 assert_eq!(1, stmts.len());
524 assert_matches!(&stmts[0], Statement::ShowIndex { .. });
525 match &stmts[0] {
526 Statement::ShowIndex(show) => {
527 let new_sql = format!("\n{}", show);
528 assert_eq!(
529 r#"
530SHOW INDEX IN t1 IN d1"#,
531 &new_sql
532 );
533 }
534 _ => {
535 unreachable!();
536 }
537 }
538 }
539
540 #[test]
541 fn test_display_show_columns() {
542 let sql = r"show full columns in t1 in d1;";
543 let stmts: Vec<Statement> =
544 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
545 .unwrap();
546 assert_eq!(1, stmts.len());
547 assert_matches!(&stmts[0], Statement::ShowColumns { .. });
548 match &stmts[0] {
549 Statement::ShowColumns(show) => {
550 let new_sql = format!("\n{}", show);
551 assert_eq!(
552 r#"
553SHOW FULL COLUMNS IN t1 IN d1"#,
554 &new_sql
555 );
556 }
557 _ => {
558 unreachable!();
559 }
560 }
561 }
562
563 #[test]
564 fn test_display_show_tables() {
565 let sql = r"show full tables in d1;";
566 let stmts: Vec<Statement> =
567 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
568 .unwrap();
569 assert_eq!(1, stmts.len());
570 assert_matches!(&stmts[0], Statement::ShowTables { .. });
571 match &stmts[0] {
572 Statement::ShowTables(show) => {
573 let new_sql = format!("\n{}", show);
574 assert_eq!(
575 r#"
576SHOW FULL TABLES IN d1"#,
577 &new_sql
578 );
579 }
580 _ => {
581 unreachable!();
582 }
583 }
584
585 let sql = r"show full tables;";
586 let stmts: Vec<Statement> =
587 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
588 .unwrap();
589 assert_eq!(1, stmts.len());
590 assert_matches!(&stmts[0], Statement::ShowTables { .. });
591 match &stmts[0] {
592 Statement::ShowTables(show) => {
593 let new_sql = format!("\n{}", show);
594 assert_eq!(
595 r#"
596SHOW FULL TABLES"#,
597 &new_sql
598 );
599 }
600 _ => {
601 unreachable!();
602 }
603 }
604 }
605
606 #[test]
607 fn test_display_show_views() {
608 let sql = r"show views in d1;";
609 let stmts: Vec<Statement> =
610 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
611 .unwrap();
612 assert_eq!(1, stmts.len());
613 assert_matches!(&stmts[0], Statement::ShowViews { .. });
614 match &stmts[0] {
615 Statement::ShowViews(show) => {
616 let new_sql = format!("\n{}", show);
617 assert_eq!(
618 r#"
619SHOW VIEWS IN d1"#,
620 &new_sql
621 );
622 }
623 _ => {
624 unreachable!();
625 }
626 }
627
628 let sql = r"show views;";
629 let stmts: Vec<Statement> =
630 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
631 .unwrap();
632 assert_eq!(1, stmts.len());
633 assert_matches!(&stmts[0], Statement::ShowViews { .. });
634 match &stmts[0] {
635 Statement::ShowViews(show) => {
636 let new_sql = format!("\n{}", show);
637 assert_eq!(
638 r#"
639SHOW VIEWS"#,
640 &new_sql
641 );
642 }
643 _ => {
644 unreachable!();
645 }
646 }
647 }
648
649 #[test]
650 fn test_display_show_flows() {
651 let sql = r"show flows in d1;";
652 let stmts: Vec<Statement> =
653 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
654 .unwrap();
655 assert_eq!(1, stmts.len());
656 assert_matches!(&stmts[0], Statement::ShowFlows { .. });
657 match &stmts[0] {
658 Statement::ShowFlows(show) => {
659 let new_sql = format!("\n{}", show);
660 assert_eq!(
661 r#"
662SHOW FLOWS IN d1"#,
663 &new_sql
664 );
665 }
666 _ => {
667 unreachable!();
668 }
669 }
670
671 let sql = r"show flows;";
672 let stmts: Vec<Statement> =
673 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
674 .unwrap();
675 assert_eq!(1, stmts.len());
676 assert_matches!(&stmts[0], Statement::ShowFlows { .. });
677 match &stmts[0] {
678 Statement::ShowFlows(show) => {
679 let new_sql = format!("\n{}", show);
680 assert_eq!(
681 r#"
682SHOW FLOWS"#,
683 &new_sql
684 );
685 }
686 _ => {
687 unreachable!("{:?}", &stmts[0]);
688 }
689 }
690 }
691
692 #[test]
693 fn test_display_show_databases() {
694 let sql = r"show databases;";
695 let stmts: Vec<Statement> =
696 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
697 .unwrap();
698 assert_eq!(1, stmts.len());
699 assert_matches!(&stmts[0], Statement::ShowDatabases { .. });
700 match &stmts[0] {
701 Statement::ShowDatabases(show) => {
702 let new_sql = format!("\n{}", show);
703 assert_eq!(
704 r#"
705SHOW DATABASES"#,
706 &new_sql
707 );
708 }
709 _ => {
710 unreachable!();
711 }
712 }
713 }
714}