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#[cfg(test)]
325mod tests {
326 use std::assert_matches::assert_matches;
327
328 use sqlparser::ast::UnaryOperator;
329
330 use super::*;
331 use crate::dialect::GreptimeDbDialect;
332 use crate::parser::{ParseOptions, ParserContext};
333 use crate::statements::statement::Statement;
334
335 #[test]
336 fn test_kind_display() {
337 assert_eq!("", format!("{}", ShowKind::All));
338 assert_eq!(
339 "LIKE test",
340 format!("{}", ShowKind::Like(Ident::new("test")),)
341 );
342 assert_eq!(
343 "WHERE NOT a",
344 format!(
345 "{}",
346 ShowKind::Where(Expr::UnaryOp {
347 op: UnaryOperator::Not,
348 expr: Box::new(Expr::Identifier(Ident::new("a"))),
349 })
350 )
351 );
352 }
353
354 #[test]
355 pub fn test_show_database() {
356 let sql = "SHOW DATABASES";
357 let stmts =
358 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
359 .unwrap();
360 assert_eq!(1, stmts.len());
361 assert_matches!(&stmts[0], Statement::ShowDatabases { .. });
362 match &stmts[0] {
363 Statement::ShowDatabases(show) => {
364 assert_eq!(ShowKind::All, show.kind);
365 }
366 _ => {
367 unreachable!();
368 }
369 }
370 }
371
372 #[test]
373 pub fn test_show_create_table() {
374 let sql = "SHOW CREATE TABLE test";
375 let stmts: Vec<Statement> =
376 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
377 .unwrap();
378 assert_eq!(1, stmts.len());
379 assert_matches!(&stmts[0], Statement::ShowCreateTable { .. });
380 match &stmts[0] {
381 Statement::ShowCreateTable(show) => {
382 let table_name = show.table_name.to_string();
383 assert_eq!(table_name, "test");
384 assert_eq!(show.variant, ShowCreateTableVariant::Original);
385 }
386 _ => {
387 unreachable!();
388 }
389 }
390
391 let sql = "SHOW CREATE TABLE test FOR POSTGRES_FOREIGN_TABLE";
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::PostgresForeignTable);
402 }
403 _ => {
404 unreachable!();
405 }
406 }
407 }
408
409 #[test]
410 pub fn test_show_create_missing_table_name() {
411 let sql = "SHOW CREATE TABLE";
412 assert!(ParserContext::create_with_dialect(
413 sql,
414 &GreptimeDbDialect {},
415 ParseOptions::default()
416 )
417 .is_err());
418 }
419
420 #[test]
421 pub fn test_show_create_unknown_for() {
422 let sql = "SHOW CREATE TABLE t FOR UNKNOWN";
423 assert!(ParserContext::create_with_dialect(
424 sql,
425 &GreptimeDbDialect {},
426 ParseOptions::default()
427 )
428 .is_err());
429 }
430
431 #[test]
432 pub fn test_show_create_flow() {
433 let sql = "SHOW CREATE FLOW test";
434 let stmts: Vec<Statement> =
435 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
436 .unwrap();
437 assert_eq!(1, stmts.len());
438 assert_matches!(&stmts[0], Statement::ShowCreateFlow { .. });
439 match &stmts[0] {
440 Statement::ShowCreateFlow(show) => {
441 let flow_name = show.flow_name.to_string();
442 assert_eq!(flow_name, "test");
443 }
444 _ => {
445 unreachable!();
446 }
447 }
448 }
449 #[test]
450 pub fn test_show_create_missing_flow() {
451 let sql = "SHOW CREATE FLOW";
452 assert!(ParserContext::create_with_dialect(
453 sql,
454 &GreptimeDbDialect {},
455 ParseOptions::default()
456 )
457 .is_err());
458 }
459
460 #[test]
461 fn test_display_show_variables() {
462 let sql = r"show variables v1;";
463 let stmts: Vec<Statement> =
464 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
465 .unwrap();
466 assert_eq!(1, stmts.len());
467 assert_matches!(&stmts[0], Statement::ShowVariables { .. });
468 match &stmts[0] {
469 Statement::ShowVariables(show) => {
470 let new_sql = format!("\n{}", show);
471 assert_eq!(
472 r#"
473SHOW VARIABLES v1"#,
474 &new_sql
475 );
476 }
477 _ => {
478 unreachable!();
479 }
480 }
481 }
482
483 #[test]
484 fn test_display_show_create_table() {
485 let sql = r"show create table monitor;";
486 let stmts: Vec<Statement> =
487 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
488 .unwrap();
489 assert_eq!(1, stmts.len());
490 assert_matches!(&stmts[0], Statement::ShowCreateTable { .. });
491 match &stmts[0] {
492 Statement::ShowCreateTable(show) => {
493 let new_sql = format!("\n{}", show);
494 assert_eq!(
495 r#"
496SHOW CREATE TABLE monitor"#,
497 &new_sql
498 );
499 }
500 _ => {
501 unreachable!();
502 }
503 }
504 }
505
506 #[test]
507 fn test_display_show_index() {
508 let sql = r"show index from t1 from d1;";
509 let stmts: Vec<Statement> =
510 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
511 .unwrap();
512 assert_eq!(1, stmts.len());
513 assert_matches!(&stmts[0], Statement::ShowIndex { .. });
514 match &stmts[0] {
515 Statement::ShowIndex(show) => {
516 let new_sql = format!("\n{}", show);
517 assert_eq!(
518 r#"
519SHOW INDEX IN t1 IN d1"#,
520 &new_sql
521 );
522 }
523 _ => {
524 unreachable!();
525 }
526 }
527 }
528
529 #[test]
530 fn test_display_show_columns() {
531 let sql = r"show full columns in t1 in d1;";
532 let stmts: Vec<Statement> =
533 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
534 .unwrap();
535 assert_eq!(1, stmts.len());
536 assert_matches!(&stmts[0], Statement::ShowColumns { .. });
537 match &stmts[0] {
538 Statement::ShowColumns(show) => {
539 let new_sql = format!("\n{}", show);
540 assert_eq!(
541 r#"
542SHOW FULL COLUMNS IN t1 IN d1"#,
543 &new_sql
544 );
545 }
546 _ => {
547 unreachable!();
548 }
549 }
550 }
551
552 #[test]
553 fn test_display_show_tables() {
554 let sql = r"show full tables in d1;";
555 let stmts: Vec<Statement> =
556 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
557 .unwrap();
558 assert_eq!(1, stmts.len());
559 assert_matches!(&stmts[0], Statement::ShowTables { .. });
560 match &stmts[0] {
561 Statement::ShowTables(show) => {
562 let new_sql = format!("\n{}", show);
563 assert_eq!(
564 r#"
565SHOW FULL TABLES IN d1"#,
566 &new_sql
567 );
568 }
569 _ => {
570 unreachable!();
571 }
572 }
573
574 let sql = r"show full tables;";
575 let stmts: Vec<Statement> =
576 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
577 .unwrap();
578 assert_eq!(1, stmts.len());
579 assert_matches!(&stmts[0], Statement::ShowTables { .. });
580 match &stmts[0] {
581 Statement::ShowTables(show) => {
582 let new_sql = format!("\n{}", show);
583 assert_eq!(
584 r#"
585SHOW FULL TABLES"#,
586 &new_sql
587 );
588 }
589 _ => {
590 unreachable!();
591 }
592 }
593 }
594
595 #[test]
596 fn test_display_show_views() {
597 let sql = r"show views in d1;";
598 let stmts: Vec<Statement> =
599 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
600 .unwrap();
601 assert_eq!(1, stmts.len());
602 assert_matches!(&stmts[0], Statement::ShowViews { .. });
603 match &stmts[0] {
604 Statement::ShowViews(show) => {
605 let new_sql = format!("\n{}", show);
606 assert_eq!(
607 r#"
608SHOW VIEWS IN d1"#,
609 &new_sql
610 );
611 }
612 _ => {
613 unreachable!();
614 }
615 }
616
617 let sql = r"show views;";
618 let stmts: Vec<Statement> =
619 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
620 .unwrap();
621 assert_eq!(1, stmts.len());
622 assert_matches!(&stmts[0], Statement::ShowViews { .. });
623 match &stmts[0] {
624 Statement::ShowViews(show) => {
625 let new_sql = format!("\n{}", show);
626 assert_eq!(
627 r#"
628SHOW VIEWS"#,
629 &new_sql
630 );
631 }
632 _ => {
633 unreachable!();
634 }
635 }
636 }
637
638 #[test]
639 fn test_display_show_flows() {
640 let sql = r"show flows in d1;";
641 let stmts: Vec<Statement> =
642 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
643 .unwrap();
644 assert_eq!(1, stmts.len());
645 assert_matches!(&stmts[0], Statement::ShowFlows { .. });
646 match &stmts[0] {
647 Statement::ShowFlows(show) => {
648 let new_sql = format!("\n{}", show);
649 assert_eq!(
650 r#"
651SHOW FLOWS IN d1"#,
652 &new_sql
653 );
654 }
655 _ => {
656 unreachable!();
657 }
658 }
659
660 let sql = r"show flows;";
661 let stmts: Vec<Statement> =
662 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
663 .unwrap();
664 assert_eq!(1, stmts.len());
665 assert_matches!(&stmts[0], Statement::ShowFlows { .. });
666 match &stmts[0] {
667 Statement::ShowFlows(show) => {
668 let new_sql = format!("\n{}", show);
669 assert_eq!(
670 r#"
671SHOW FLOWS"#,
672 &new_sql
673 );
674 }
675 _ => {
676 unreachable!("{:?}", &stmts[0]);
677 }
678 }
679 }
680
681 #[test]
682 fn test_display_show_databases() {
683 let sql = r"show databases;";
684 let stmts: Vec<Statement> =
685 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
686 .unwrap();
687 assert_eq!(1, stmts.len());
688 assert_matches!(&stmts[0], Statement::ShowDatabases { .. });
689 match &stmts[0] {
690 Statement::ShowDatabases(show) => {
691 let new_sql = format!("\n{}", show);
692 assert_eq!(
693 r#"
694SHOW DATABASES"#,
695 &new_sql
696 );
697 }
698 _ => {
699 unreachable!();
700 }
701 }
702 }
703}