1616// under the License.
1717
1818//! [`DFParser`]: DataFusion SQL Parser based on [`sqlparser`]
19+ //!
20+ //! This parser implements DataFusion specific statements such as
21+ //! `CREATE EXTERNAL TABLE`
1922
2023use std:: collections:: VecDeque ;
2124use std:: fmt;
@@ -43,12 +46,23 @@ fn parse_file_type(s: &str) -> Result<String, ParserError> {
4346 Ok ( s. to_uppercase ( ) )
4447}
4548
46- /// DataFusion specific EXPLAIN (needed so we can EXPLAIN datafusion
47- /// specific COPY and other statements)
49+ /// DataFusion specific `EXPLAIN`
50+ ///
51+ /// Syntax:
52+ /// ```sql
53+ /// EXPLAIN <ANALYZE> <VERBOSE> [FORMAT format] statement
54+ ///```
4855#[ derive( Debug , Clone , PartialEq , Eq ) ]
4956pub struct ExplainStatement {
57+ /// `EXPLAIN ANALYZE ..`
5058 pub analyze : bool ,
59+ /// `EXPLAIN .. VERBOSE ..`
5160 pub verbose : bool ,
61+ /// `EXPLAIN .. FORMAT `
62+ pub format : Option < String > ,
63+ /// The statement to analyze. Note this is a DataFusion [`Statement`] (not a
64+ /// [`sqlparser::ast::Statement`] so that we can `EXPLAIN` `COPY` and other
65+ /// DataFusion specific statements
5266 pub statement : Box < Statement > ,
5367}
5468
@@ -57,6 +71,7 @@ impl fmt::Display for ExplainStatement {
5771 let Self {
5872 analyze,
5973 verbose,
74+ format,
6075 statement,
6176 } = self ;
6277
@@ -67,6 +82,9 @@ impl fmt::Display for ExplainStatement {
6782 if * verbose {
6883 write ! ( f, "VERBOSE " ) ?;
6984 }
85+ if let Some ( format) = format. as_ref ( ) {
86+ write ! ( f, "FORMAT {format} " ) ?;
87+ }
7088
7189 write ! ( f, "{statement}" )
7290 }
@@ -446,7 +464,6 @@ impl<'a> DFParser<'a> {
446464 self . parse_copy ( )
447465 }
448466 Keyword :: EXPLAIN => {
449- // (TODO parse all supported statements)
450467 self . parser . next_token ( ) ; // EXPLAIN
451468 self . parse_explain ( )
452469 }
@@ -620,15 +637,35 @@ impl<'a> DFParser<'a> {
620637 pub fn parse_explain ( & mut self ) -> Result < Statement , ParserError > {
621638 let analyze = self . parser . parse_keyword ( Keyword :: ANALYZE ) ;
622639 let verbose = self . parser . parse_keyword ( Keyword :: VERBOSE ) ;
640+ let format = self . parse_explain_format ( ) ?;
641+
623642 let statement = self . parse_statement ( ) ?;
624643
625644 Ok ( Statement :: Explain ( ExplainStatement {
626645 statement : Box :: new ( statement) ,
627646 analyze,
628647 verbose,
648+ format,
629649 } ) )
630650 }
631651
652+ pub fn parse_explain_format ( & mut self ) -> Result < Option < String > , ParserError > {
653+ if !self . parser . parse_keyword ( Keyword :: FORMAT ) {
654+ return Ok ( None ) ;
655+ }
656+
657+ let next_token = self . parser . next_token ( ) ;
658+ let format = match next_token. token {
659+ Token :: Word ( w) => Ok ( w. value ) ,
660+ Token :: SingleQuotedString ( w) => Ok ( w) ,
661+ Token :: DoubleQuotedString ( w) => Ok ( w) ,
662+ _ => self
663+ . parser
664+ . expected ( "an explain format like JSON or TREE" , next_token) ,
665+ } ?;
666+ Ok ( Some ( format) )
667+ }
668+
632669 /// Parse a SQL `CREATE` statement handling `CREATE EXTERNAL TABLE`
633670 pub fn parse_create ( & mut self ) -> Result < Statement , ParserError > {
634671 if self . parser . parse_keyword ( Keyword :: EXTERNAL ) {
@@ -1543,6 +1580,7 @@ mod tests {
15431580 let expected = Statement :: Explain ( ExplainStatement {
15441581 analyze,
15451582 verbose,
1583+ format : None ,
15461584 statement : Box :: new ( expected_copy) ,
15471585 } ) ;
15481586 assert_eq ! ( verified_stmt( sql) , expected) ;
0 commit comments