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!(ParserContext::create_with_dialect(
430 sql,
431 &GreptimeDbDialect {},
432 ParseOptions::default()
433 )
434 .is_err());
435 }
436
437 #[test]
438 pub fn test_show_create_unknown_for() {
439 let sql = "SHOW CREATE TABLE t FOR UNKNOWN";
440 assert!(ParserContext::create_with_dialect(
441 sql,
442 &GreptimeDbDialect {},
443 ParseOptions::default()
444 )
445 .is_err());
446 }
447
448 #[test]
449 pub fn test_show_create_flow() {
450 let sql = "SHOW CREATE FLOW test";
451 let stmts: Vec<Statement> =
452 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
453 .unwrap();
454 assert_eq!(1, stmts.len());
455 assert_matches!(&stmts[0], Statement::ShowCreateFlow { .. });
456 match &stmts[0] {
457 Statement::ShowCreateFlow(show) => {
458 let flow_name = show.flow_name.to_string();
459 assert_eq!(flow_name, "test");
460 }
461 _ => {
462 unreachable!();
463 }
464 }
465 }
466 #[test]
467 pub fn test_show_create_missing_flow() {
468 let sql = "SHOW CREATE FLOW";
469 assert!(ParserContext::create_with_dialect(
470 sql,
471 &GreptimeDbDialect {},
472 ParseOptions::default()
473 )
474 .is_err());
475 }
476
477 #[test]
478 fn test_display_show_variables() {
479 let sql = r"show variables v1;";
480 let stmts: Vec<Statement> =
481 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
482 .unwrap();
483 assert_eq!(1, stmts.len());
484 assert_matches!(&stmts[0], Statement::ShowVariables { .. });
485 match &stmts[0] {
486 Statement::ShowVariables(show) => {
487 let new_sql = format!("\n{}", show);
488 assert_eq!(
489 r#"
490SHOW VARIABLES v1"#,
491 &new_sql
492 );
493 }
494 _ => {
495 unreachable!();
496 }
497 }
498 }
499
500 #[test]
501 fn test_display_show_create_table() {
502 let sql = r"show create table monitor;";
503 let stmts: Vec<Statement> =
504 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
505 .unwrap();
506 assert_eq!(1, stmts.len());
507 assert_matches!(&stmts[0], Statement::ShowCreateTable { .. });
508 match &stmts[0] {
509 Statement::ShowCreateTable(show) => {
510 let new_sql = format!("\n{}", show);
511 assert_eq!(
512 r#"
513SHOW CREATE TABLE monitor"#,
514 &new_sql
515 );
516 }
517 _ => {
518 unreachable!();
519 }
520 }
521 }
522
523 #[test]
524 fn test_display_show_index() {
525 let sql = r"show index from t1 from d1;";
526 let stmts: Vec<Statement> =
527 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
528 .unwrap();
529 assert_eq!(1, stmts.len());
530 assert_matches!(&stmts[0], Statement::ShowIndex { .. });
531 match &stmts[0] {
532 Statement::ShowIndex(show) => {
533 let new_sql = format!("\n{}", show);
534 assert_eq!(
535 r#"
536SHOW INDEX IN t1 IN d1"#,
537 &new_sql
538 );
539 }
540 _ => {
541 unreachable!();
542 }
543 }
544 }
545
546 #[test]
547 fn test_display_show_columns() {
548 let sql = r"show full columns in t1 in d1;";
549 let stmts: Vec<Statement> =
550 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
551 .unwrap();
552 assert_eq!(1, stmts.len());
553 assert_matches!(&stmts[0], Statement::ShowColumns { .. });
554 match &stmts[0] {
555 Statement::ShowColumns(show) => {
556 let new_sql = format!("\n{}", show);
557 assert_eq!(
558 r#"
559SHOW FULL COLUMNS IN t1 IN d1"#,
560 &new_sql
561 );
562 }
563 _ => {
564 unreachable!();
565 }
566 }
567 }
568
569 #[test]
570 fn test_display_show_tables() {
571 let sql = r"show full tables in d1;";
572 let stmts: Vec<Statement> =
573 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
574 .unwrap();
575 assert_eq!(1, stmts.len());
576 assert_matches!(&stmts[0], Statement::ShowTables { .. });
577 match &stmts[0] {
578 Statement::ShowTables(show) => {
579 let new_sql = format!("\n{}", show);
580 assert_eq!(
581 r#"
582SHOW FULL TABLES IN d1"#,
583 &new_sql
584 );
585 }
586 _ => {
587 unreachable!();
588 }
589 }
590
591 let sql = r"show full tables;";
592 let stmts: Vec<Statement> =
593 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
594 .unwrap();
595 assert_eq!(1, stmts.len());
596 assert_matches!(&stmts[0], Statement::ShowTables { .. });
597 match &stmts[0] {
598 Statement::ShowTables(show) => {
599 let new_sql = format!("\n{}", show);
600 assert_eq!(
601 r#"
602SHOW FULL TABLES"#,
603 &new_sql
604 );
605 }
606 _ => {
607 unreachable!();
608 }
609 }
610 }
611
612 #[test]
613 fn test_display_show_views() {
614 let sql = r"show views in d1;";
615 let stmts: Vec<Statement> =
616 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
617 .unwrap();
618 assert_eq!(1, stmts.len());
619 assert_matches!(&stmts[0], Statement::ShowViews { .. });
620 match &stmts[0] {
621 Statement::ShowViews(show) => {
622 let new_sql = format!("\n{}", show);
623 assert_eq!(
624 r#"
625SHOW VIEWS IN d1"#,
626 &new_sql
627 );
628 }
629 _ => {
630 unreachable!();
631 }
632 }
633
634 let sql = r"show views;";
635 let stmts: Vec<Statement> =
636 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
637 .unwrap();
638 assert_eq!(1, stmts.len());
639 assert_matches!(&stmts[0], Statement::ShowViews { .. });
640 match &stmts[0] {
641 Statement::ShowViews(show) => {
642 let new_sql = format!("\n{}", show);
643 assert_eq!(
644 r#"
645SHOW VIEWS"#,
646 &new_sql
647 );
648 }
649 _ => {
650 unreachable!();
651 }
652 }
653 }
654
655 #[test]
656 fn test_display_show_flows() {
657 let sql = r"show flows in d1;";
658 let stmts: Vec<Statement> =
659 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
660 .unwrap();
661 assert_eq!(1, stmts.len());
662 assert_matches!(&stmts[0], Statement::ShowFlows { .. });
663 match &stmts[0] {
664 Statement::ShowFlows(show) => {
665 let new_sql = format!("\n{}", show);
666 assert_eq!(
667 r#"
668SHOW FLOWS IN d1"#,
669 &new_sql
670 );
671 }
672 _ => {
673 unreachable!();
674 }
675 }
676
677 let sql = r"show flows;";
678 let stmts: Vec<Statement> =
679 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
680 .unwrap();
681 assert_eq!(1, stmts.len());
682 assert_matches!(&stmts[0], Statement::ShowFlows { .. });
683 match &stmts[0] {
684 Statement::ShowFlows(show) => {
685 let new_sql = format!("\n{}", show);
686 assert_eq!(
687 r#"
688SHOW FLOWS"#,
689 &new_sql
690 );
691 }
692 _ => {
693 unreachable!("{:?}", &stmts[0]);
694 }
695 }
696 }
697
698 #[test]
699 fn test_display_show_databases() {
700 let sql = r"show databases;";
701 let stmts: Vec<Statement> =
702 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
703 .unwrap();
704 assert_eq!(1, stmts.len());
705 assert_matches!(&stmts[0], Statement::ShowDatabases { .. });
706 match &stmts[0] {
707 Statement::ShowDatabases(show) => {
708 let new_sql = format!("\n{}", show);
709 assert_eq!(
710 r#"
711SHOW DATABASES"#,
712 &new_sql
713 );
714 }
715 _ => {
716 unreachable!();
717 }
718 }
719 }
720}