Skip to content

Commit 3bb9a70

Browse files
committed
fix: Fix parse_sql_expr not handling alias
1 parent a53b974 commit 3bb9a70

File tree

3 files changed

+53
-13
lines changed

3 files changed

+53
-13
lines changed

datafusion/core/src/execution/session_state.rs

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ use datafusion_sql::planner::{ContextProvider, ParserOptions, PlannerContext, Sq
6969
use itertools::Itertools;
7070
use log::{debug, info};
7171
use object_store::ObjectStore;
72-
use sqlparser::ast::Expr as SQLExpr;
72+
use sqlparser::ast::{Expr as SQLExpr, ExprWithAlias as SQLExprWithAlias};
7373
use sqlparser::dialect::dialect_from_str;
7474
use std::any::Any;
7575
use std::collections::hash_map::Entry;
@@ -501,12 +501,23 @@ impl SessionState {
501501
sql: &str,
502502
dialect: &str,
503503
) -> datafusion_common::Result<SQLExpr> {
504+
self.sql_to_expr_with_alias(sql, dialect).map(|x|x.expr)
505+
}
506+
507+
/// parse a sql string into a sqlparser-rs AST [`SQLExprWithAlias`].
508+
///
509+
/// See [`Self::create_logical_expr`] for parsing sql to [`Expr`].
510+
pub fn sql_to_expr_with_alias(
511+
&self,
512+
sql: &str,
513+
dialect: &str,
514+
)-> datafusion_common::Result<SQLExprWithAlias> {
504515
let dialect = dialect_from_str(dialect).ok_or_else(|| {
505-
plan_datafusion_err!(
506-
"Unsupported SQL dialect: {dialect}. Available dialects: \
507-
Generic, MySQL, PostgreSQL, Hive, SQLite, Snowflake, Redshift, \
508-
MsSQL, ClickHouse, BigQuery, Ansi."
509-
)
516+
plan_datafusion_err!(
517+
"Unsupported SQL dialect: {dialect}. Available dialects: \
518+
Generic, MySQL, PostgreSQL, Hive, SQLite, Snowflake, Redshift, \
519+
MsSQL, ClickHouse, BigQuery, Ansi."
520+
)
510521
})?;
511522

512523
let expr = DFParser::parse_sql_into_expr_with_dialect(sql, dialect.as_ref())?;
@@ -604,15 +615,15 @@ impl SessionState {
604615
) -> datafusion_common::Result<Expr> {
605616
let dialect = self.config.options().sql_parser.dialect.as_str();
606617

607-
let sql_expr = self.sql_to_expr(sql, dialect)?;
618+
let sql_expr = self.sql_to_expr_with_alias(sql, dialect)?;
608619

609620
let provider = SessionContextProvider {
610621
state: self,
611622
tables: HashMap::new(),
612623
};
613624

614625
let query = SqlToRel::new_with_options(&provider, self.get_parser_options());
615-
query.sql_to_expr(sql_expr, df_schema, &mut PlannerContext::new())
626+
query.sql_to_expr_with_alias(sql_expr, df_schema, &mut PlannerContext::new())
616627
}
617628

618629
/// Returns the [`Analyzer`] for this session

datafusion/sql/src/expr/mod.rs

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ use datafusion_expr::planner::{
2323
use recursive::recursive;
2424
use sqlparser::ast::{
2525
BinaryOperator, CastFormat, CastKind, DataType as SQLDataType, DictionaryField,
26-
Expr as SQLExpr, MapEntry, StructField, Subscript, TrimWhereField, Value,
26+
Expr as SQLExpr, ExprWithAlias as SQLExprWithAlias, MapEntry, StructField, Subscript,
27+
TrimWhereField, Value,
2728
};
2829

2930
use datafusion_common::{
@@ -50,6 +51,19 @@ mod unary_op;
5051
mod value;
5152

5253
impl<'a, S: ContextProvider> SqlToRel<'a, S> {
54+
pub(crate) fn sql_expr_to_logical_expr_with_alias(
55+
&self,
56+
sql: SQLExprWithAlias,
57+
schema: &DFSchema,
58+
planner_context: &mut PlannerContext,
59+
) -> Result<Expr> {
60+
let mut expr =
61+
self.sql_expr_to_logical_expr(sql.expr, schema, planner_context)?;
62+
if let Some(alias) = sql.alias {
63+
expr = expr.alias(alias.value);
64+
}
65+
Ok(expr)
66+
}
5367
pub(crate) fn sql_expr_to_logical_expr(
5468
&self,
5569
sql: SQLExpr,
@@ -131,6 +145,20 @@ impl<'a, S: ContextProvider> SqlToRel<'a, S> {
131145
)))
132146
}
133147

148+
pub fn sql_to_expr_with_alias(
149+
&self,
150+
sql: SQLExprWithAlias,
151+
schema: &DFSchema,
152+
planner_context: &mut PlannerContext,
153+
) -> Result<Expr> {
154+
let mut expr =
155+
self.sql_expr_to_logical_expr_with_alias(sql, schema, planner_context)?;
156+
expr = self.rewrite_partial_qualifier(expr, schema);
157+
self.validate_schema_satisfies_exprs(schema, &[expr.clone()])?;
158+
let (expr, _) = expr.infer_placeholder_types(schema)?;
159+
Ok(expr)
160+
}
161+
134162
/// Generate a relational expression from a SQL expression
135163
pub fn sql_to_expr(
136164
&self,

datafusion/sql/src/parser.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,10 @@
2020
use std::collections::VecDeque;
2121
use std::fmt;
2222

23+
use sqlparser::ast::ExprWithAlias;
2324
use sqlparser::{
2425
ast::{
25-
ColumnDef, ColumnOptionDef, Expr, ObjectName, OrderByExpr, Query,
26+
ColumnDef, ColumnOptionDef, ObjectName, OrderByExpr, Query,
2627
Statement as SQLStatement, TableConstraint, Value,
2728
},
2829
dialect::{keywords::Keyword, Dialect, GenericDialect},
@@ -328,7 +329,7 @@ impl<'a> DFParser<'a> {
328329
pub fn parse_sql_into_expr_with_dialect(
329330
sql: &str,
330331
dialect: &dyn Dialect,
331-
) -> Result<Expr, ParserError> {
332+
) -> Result<ExprWithAlias, ParserError> {
332333
let mut parser = DFParser::new_with_dialect(sql, dialect)?;
333334
parser.parse_expr()
334335
}
@@ -377,7 +378,7 @@ impl<'a> DFParser<'a> {
377378
}
378379
}
379380

380-
pub fn parse_expr(&mut self) -> Result<Expr, ParserError> {
381+
pub fn parse_expr(&mut self) -> Result<ExprWithAlias, ParserError> {
381382
if let Token::Word(w) = self.parser.peek_token().token {
382383
match w.keyword {
383384
Keyword::CREATE | Keyword::COPY | Keyword::EXPLAIN => {
@@ -387,7 +388,7 @@ impl<'a> DFParser<'a> {
387388
}
388389
}
389390

390-
self.parser.parse_expr()
391+
self.parser.parse_expr_with_alias()
391392
}
392393

393394
/// Parse a SQL `COPY TO` statement

0 commit comments

Comments
 (0)