File tree Expand file tree Collapse file tree 4 files changed +40
-1
lines changed
Expand file tree Collapse file tree 4 files changed +40
-1
lines changed Original file line number Diff line number Diff line change @@ -1135,6 +1135,12 @@ pub enum TableFactor {
11351135 subquery : Box < Query > ,
11361136 alias : Option < TableAlias > ,
11371137 } ,
1138+ /// A pass-through query string that is not parsed.
1139+ /// This is useful while building/rewriting queries with a known valid SQL string and to avoid parsing it.
1140+ PassThroughQuery {
1141+ query : String ,
1142+ alias : Option < TableAlias > ,
1143+ } ,
11381144 /// `TABLE(<expr>)[ AS <alias> ]`
11391145 TableFunction {
11401146 expr : Expr ,
@@ -1767,6 +1773,13 @@ impl fmt::Display for TableFactor {
17671773 }
17681774 Ok ( ( ) )
17691775 }
1776+ TableFactor :: PassThroughQuery { query, alias } => {
1777+ write ! ( f, "({query})" ) ?;
1778+ if let Some ( alias) = alias {
1779+ write ! ( f, " AS {alias}" ) ?;
1780+ }
1781+ Ok ( ( ) )
1782+ }
17701783 TableFactor :: Function {
17711784 lateral,
17721785 name,
Original file line number Diff line number Diff line change @@ -1876,6 +1876,8 @@ impl Spanned for TableFactor {
18761876 } => subquery
18771877 . span ( )
18781878 . union_opt ( & alias. as_ref ( ) . map ( |alias| alias. span ( ) ) ) ,
1879+ // This is usually created at runtime, so we don't have a span for it
1880+ TableFactor :: PassThroughQuery { query : _, alias : _ } => Span :: empty ( ) ,
18791881 TableFactor :: TableFunction { expr, alias } => expr
18801882 . span ( )
18811883 . union_opt ( & alias. as_ref ( ) . map ( |alias| alias. span ( ) ) ) ,
Original file line number Diff line number Diff line change @@ -11971,7 +11971,8 @@ impl<'a> Parser<'a> {
1197111971 | TableFactor::Pivot { alias, .. }
1197211972 | TableFactor::Unpivot { alias, .. }
1197311973 | TableFactor::MatchRecognize { alias, .. }
11974- | TableFactor::NestedJoin { alias, .. } => {
11974+ | TableFactor::NestedJoin { alias, .. }
11975+ | TableFactor::PassThroughQuery { alias, .. } => {
1197511976 // but not `FROM (mytable AS alias1) AS alias2`.
1197611977 if let Some(inner_alias) = alias {
1197711978 return Err(ParserError::ParserError(format!(
Original file line number Diff line number Diff line change @@ -14124,6 +14124,29 @@ fn parse_select_without_projection() {
1412414124 dialects. verified_stmt ( "SELECT FROM users" ) ;
1412514125}
1412614126
14127+ #[ test]
14128+ fn ast_with_pass_through_query ( ) {
14129+ let sql = "SELECT * FROM t1 AS t2" ;
14130+ let mut ast = all_dialects ( ) . verified_stmt ( sql) ;
14131+ let Statement :: Query ( ref mut query) = ast else {
14132+ panic ! ( "Expected Query" ) ;
14133+ } ;
14134+ let SetExpr :: Select ( ref mut select) = * query. body else {
14135+ panic ! ( "Expected SetExpr::Select" ) ;
14136+ } ;
14137+ let from = select. from . get_mut ( 0 ) . unwrap ( ) ;
14138+ from. relation = TableFactor :: PassThroughQuery {
14139+ query : "SELECT * FROM tx" . to_string ( ) ,
14140+ alias : Some ( TableAlias {
14141+ name : Ident :: new ( "ty" ) ,
14142+ columns : vec ! [ ] ,
14143+ } ) ,
14144+ } ;
14145+
14146+ // After modifying the AST, the SQL representation should be different
14147+ assert_eq ! ( ast. to_string( ) , "SELECT * FROM (SELECT * FROM tx) AS ty" ) ;
14148+ }
14149+
1412714150#[ test]
1412814151fn parse_update_from_before_select ( ) {
1412914152 verified_stmt ( "UPDATE t1 FROM (SELECT name, id FROM t1 GROUP BY id) AS t2 SET name = t2.name WHERE t1.id = t2.id" ) ;
You can’t perform that action at this time.
0 commit comments