Skip to main content

linkrs_query/parser/parsing/
show_parser.rs

1//! SHOW Statement Parsing Module
2//!
3//! Responsible for parsing SHOW statements, including SHOW SESSIONS, SHOW QUERIES,
4//! SHOW CONFIGS, SHOW SPACES, SHOW TAGS, SHOW EDGES, SHOW USERS, SHOW ROLES,
5//! and SHOW CREATE.
6
7use crate::parser::ast::stmt::*;
8use crate::parser::core::error::{ParseError, ParseErrorKind};
9use crate::parser::parsing::parse_context::ParseContext;
10use crate::parser::parsing::util_stmt_parser::UtilStmtParser;
11use crate::parser::TokenKind;
12
13/// SHOW Statement Parser
14pub struct ShowParser;
15
16impl Default for ShowParser {
17    fn default() -> Self {
18        Self
19    }
20}
21
22impl ShowParser {
23    pub fn new() -> Self {
24        Self
25    }
26
27    /// Parse extended SHOW statements (SESSIONS, QUERIES, CONFIGS, SPACES, etc.)
28    pub fn parse_show_statement_extended(
29        &mut self,
30        ctx: &mut ParseContext,
31    ) -> Result<Stmt, ParseError> {
32        let start_span = ctx.current_span();
33        ctx.expect_token(TokenKind::Show)?;
34
35        if ctx.check_token(TokenKind::Sessions) {
36            ctx.expect_token(TokenKind::Sessions)?;
37            let span = ctx.span_since(start_span.start);
38            Ok(Stmt::ShowSessions(ShowSessionsStmt { span }))
39        } else if ctx.check_token(TokenKind::Queries) {
40            ctx.expect_token(TokenKind::Queries)?;
41            let span = ctx.span_since(start_span.start);
42            Ok(Stmt::ShowQueries(ShowQueriesStmt { span }))
43        } else if ctx.check_token(TokenKind::Configs) {
44            ctx.expect_token(TokenKind::Configs)?;
45            // Module names share the identifier vocabulary with UPDATE
46            // CONFIGS (reserved words like `transaction` included): probe
47            // with a checkpoint so bare `SHOW CONFIGS` consumes nothing.
48            let ckpt = ctx.checkpoint();
49            let module = match ctx.expect_identifier() {
50                Ok(name) => Some(name),
51                Err(_) => {
52                    ctx.restore(ckpt);
53                    None
54                }
55            };
56            let span = ctx.span_since(start_span.start);
57            Ok(Stmt::ShowConfigs(ShowConfigsStmt { span, module }))
58        } else if ctx.check_token(TokenKind::Spaces) {
59            ctx.expect_token(TokenKind::Spaces)?;
60            let span = ctx.span_since(start_span.start);
61            Ok(Stmt::Show(ShowStmt {
62                span,
63                target: ShowTarget::Spaces,
64            }))
65        } else if ctx.check_token(TokenKind::Tags) {
66            ctx.expect_token(TokenKind::Tags)?;
67            let span = ctx.span_since(start_span.start);
68            Ok(Stmt::Show(ShowStmt {
69                span,
70                target: ShowTarget::Tags,
71            }))
72        } else if ctx.check_token(TokenKind::Edges) {
73            ctx.expect_token(TokenKind::Edges)?;
74            let span = ctx.span_since(start_span.start);
75            Ok(Stmt::Show(ShowStmt {
76                span,
77                target: ShowTarget::Edges,
78            }))
79        } else if ctx.check_token(TokenKind::Indexes) {
80            ctx.expect_token(TokenKind::Indexes)?;
81            let span = ctx.span_since(start_span.start);
82            Ok(Stmt::Show(ShowStmt {
83                span,
84                target: ShowTarget::Indexes,
85            }))
86        } else if ctx.check_token(TokenKind::Index) {
87            ctx.expect_token(TokenKind::Index)?;
88            let index_name = ctx.expect_identifier()?;
89            let span = ctx.span_since(start_span.start);
90            Ok(Stmt::Show(ShowStmt {
91                span,
92                target: ShowTarget::Index(index_name),
93            }))
94        } else if ctx.check_token(TokenKind::Stats) {
95            ctx.expect_token(TokenKind::Stats)?;
96            let span = ctx.span_since(start_span.start);
97            Ok(Stmt::Show(ShowStmt {
98                span,
99                target: ShowTarget::Stats,
100            }))
101        } else if ctx.check_token(TokenKind::Users) {
102            ctx.expect_token(TokenKind::Users)?;
103            let span = ctx.span_since(start_span.start);
104            Ok(Stmt::ShowUsers(ShowUsersStmt { span }))
105        } else if ctx.check_token(TokenKind::Roles) {
106            UtilStmtParser::new().parse_show_roles_internal(ctx, start_span)
107        } else if ctx.check_token(TokenKind::Create) {
108            UtilStmtParser::new().parse_show_create_internal(ctx, start_span)
109        } else if ctx.check_token(TokenKind::Functions) {
110            ctx.expect_token(TokenKind::Functions)?;
111            let span = ctx.span_since(start_span.start);
112            Ok(Stmt::Show(ShowStmt {
113                span,
114                target: ShowTarget::Functions,
115            }))
116        } else if ctx.check_token(TokenKind::Graphs) {
117            ctx.expect_token(TokenKind::Graphs)?;
118            let span = ctx.span_since(start_span.start);
119            Ok(Stmt::Show(ShowStmt {
120                span,
121                target: ShowTarget::Graphs,
122            }))
123        } else if ctx.check_token(TokenKind::Macros) {
124            ctx.expect_token(TokenKind::Macros)?;
125            let span = ctx.span_since(start_span.start);
126            Ok(Stmt::Show(ShowStmt {
127                span,
128                target: ShowTarget::Macros,
129            }))
130        } else if ctx.check_keyword("ATTACHED") {
131            ctx.consume_keyword("ATTACHED")?;
132            ctx.consume_keyword("DATABASES")?;
133            let span = ctx.span_since(start_span.start);
134            Ok(Stmt::Show(ShowStmt {
135                span,
136                target: ShowTarget::AttachedDatabases,
137            }))
138        } else if ctx.check_keyword("EXTENSIONS") {
139            ctx.consume_keyword("EXTENSIONS")?;
140            let span = ctx.span_since(start_span.start);
141            Ok(Stmt::Show(ShowStmt {
142                span,
143                target: ShowTarget::Extensions,
144            }))
145        } else {
146            Err(ParseError::new(
147                ParseErrorKind::SyntaxError,
148                format!(
149                    "Unknown SHOW target: {:?}; supported targets: SESSIONS, QUERIES, CONFIGS, \
150                     SPACES, TAGS, EDGES, INDEXES, INDEX, STATS, USERS, ROLES, CREATE, \
151                     FUNCTIONS, GRAPHS, MACROS, ATTACHED DATABASES, EXTENSIONS",
152                    ctx.peek_token().kind
153                ),
154                ctx.current_position(),
155            ))
156        }
157    }
158}