Skip to content

Commit fce3ce8

Browse files
committed
add passthrough query as a tablefactor
1 parent 761c86e commit fce3ce8

File tree

4 files changed

+40
-1
lines changed

4 files changed

+40
-1
lines changed

src/ast/query.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff 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,

src/ast/spans.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff 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())),

src/parser/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff 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!(

tests/sqlparser_common.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff 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]
1412814151
fn 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");

0 commit comments

Comments
 (0)