From 92ea0f419ff878cb949b0a666c9c00f0408b89f9 Mon Sep 17 00:00:00 2001 From: Yoav Cohen Date: Mon, 14 Oct 2024 22:19:15 +0200 Subject: [PATCH] Go back to helper function --- src/dialect/mod.rs | 8 ++++++- src/parser/mod.rs | 48 +++++++++++++++++++++------------------ tests/sqlparser_common.rs | 12 ++++++++++ tests/sqlparser_mssql.rs | 11 --------- 4 files changed, 45 insertions(+), 34 deletions(-) diff --git a/src/dialect/mod.rs b/src/dialect/mod.rs index 01cceac36..33e180877 100644 --- a/src/dialect/mod.rs +++ b/src/dialect/mod.rs @@ -562,7 +562,13 @@ pub trait Dialect: Debug + Any { false } - /// For example: SELECT col_alias = col FROM tbl + /// Returns true if this dialect supports treating the equals operator `=` within a [`SelectItem`] + /// as an alias assignment operator, rather than a boolean expression. + /// For example: the following statements are equivalent for such a dialect: + /// ```sql + /// SELECT col_alias = col FROM tbl; + /// SELECT col_alias AS col FROM tbl; + /// ``` fn supports_eq_alias_assigment(&self) -> bool { false } diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 138d30ca8..249a6257c 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -11174,29 +11174,11 @@ impl<'a> Parser<'a> { ) } expr => { - // Parse a [`SelectItem`] based on an [MsSql] syntax that uses the equal sign - // to denote an alias, for example: SELECT col_alias = col FROM tbl - // [MsSql]: https://learn.microsoft.com/en-us/sql/t-sql/queries/select-examples-transact-sql?view=sql-server-ver16#b-use-select-with-column-headings-and-calculations - let expr = if self.dialect.supports_eq_alias_assigment() { - if let Expr::BinaryOp { - ref left, - op: BinaryOperator::Eq, - ref right, - } = expr - { - if let Expr::Identifier(alias) = left.as_ref() { - return Ok(SelectItem::ExprWithAlias { - expr: *right.clone(), - alias: alias.clone(), - }); - } + if self.dialect.supports_eq_alias_assigment() { + if let Some(select_item) = Self::maybe_unpack_alias_assignment(&expr) { + return Ok(select_item); } - expr - } else { - expr - }; - - // Parse the common AS keyword for aliasing a column + } self.parse_optional_alias(keywords::RESERVED_FOR_COLUMN_ALIAS) .map(|alias| match alias { Some(alias) => SelectItem::ExprWithAlias { expr, alias }, @@ -12212,6 +12194,28 @@ impl<'a> Parser<'a> { } false } + + /// Parse a [`SelectItem`] based on an [MsSql] syntax that uses the equal sign + /// to denote an alias, for example: SELECT col_alias = col FROM tbl + /// [MsSql]: + fn maybe_unpack_alias_assignment(expr: &Expr) -> Option { + if let Expr::BinaryOp { + left, + op: BinaryOperator::Eq, + right, + .. + } = expr + { + if let Expr::Identifier(ref alias) = **left { + return Some(SelectItem::ExprWithAlias { + expr: *right.clone(), + alias: alias.clone(), + }); + } + } + + None + } } impl Word { diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs index 7140109b2..0a4fb0ccc 100644 --- a/tests/sqlparser_common.rs +++ b/tests/sqlparser_common.rs @@ -11408,3 +11408,15 @@ fn test_any_some_all_comparison() { verified_stmt("SELECT c1 FROM tbl WHERE c1 <> SOME(SELECT c2 FROM tbl)"); verified_stmt("SELECT 1 = ANY(WITH x AS (SELECT 1) SELECT * FROM x)"); } + +#[test] +fn test_alias_equal_expr() { + let dialects = all_dialects_where(|d| d.supports_eq_alias_assigment()); + let sql = r#"SELECT some_alias = some_column FROM some_table"#; + let expected = r#"SELECT some_column AS some_alias FROM some_table"#; + let _ = dialects.one_statement_parses_to(sql, expected); + + let sql = r#"SELECT some_alias = (a*b) FROM some_table"#; + let expected = r#"SELECT (a * b) AS some_alias FROM some_table"#; + let _ = dialects.one_statement_parses_to(sql, expected); +} diff --git a/tests/sqlparser_mssql.rs b/tests/sqlparser_mssql.rs index 7ebd6026a..5a2ef9e87 100644 --- a/tests/sqlparser_mssql.rs +++ b/tests/sqlparser_mssql.rs @@ -1024,17 +1024,6 @@ fn parse_create_table_with_identity_column() { } } -#[test] -fn test_alias_equal_expr() { - let sql = r#"SELECT some_alias = some_column FROM some_table"#; - let expected = r#"SELECT some_column AS some_alias FROM some_table"#; - let _ = ms().one_statement_parses_to(sql, expected); - - let sql = r#"SELECT some_alias = (a*b) FROM some_table"#; - let expected = r#"SELECT (a * b) AS some_alias FROM some_table"#; - let _ = ms().one_statement_parses_to(sql, expected); -} - fn ms() -> TestedDialects { TestedDialects { dialects: vec![Box::new(MsSqlDialect {})],