diff --git a/src/dialect/mod.rs b/src/dialect/mod.rs index 744f5a8c8..871055685 100644 --- a/src/dialect/mod.rs +++ b/src/dialect/mod.rs @@ -561,6 +561,17 @@ pub trait Dialect: Debug + Any { fn supports_asc_desc_in_column_definition(&self) -> bool { false } + + /// 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 + } } /// This represents the operators for which precedence must be defined diff --git a/src/dialect/mssql.rs b/src/dialect/mssql.rs index a9d296be3..cace372c0 100644 --- a/src/dialect/mssql.rs +++ b/src/dialect/mssql.rs @@ -49,4 +49,8 @@ impl Dialect for MsSqlDialect { fn supports_connect_by(&self) -> bool { true } + + fn supports_eq_alias_assigment(&self) -> bool { + true + } } diff --git a/src/parser/mod.rs b/src/parser/mod.rs index b4c0487b4..842e85c12 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -11181,6 +11181,24 @@ impl<'a> Parser<'a> { self.peek_token().location ) } + Expr::BinaryOp { + left, + op: BinaryOperator::Eq, + right, + } if self.dialect.supports_eq_alias_assigment() + && matches!(left.as_ref(), Expr::Identifier(_)) => + { + let Expr::Identifier(alias) = *left else { + return parser_err!( + "BUG: expected identifier expression as alias", + self.peek_token().location + ); + }; + Ok(SelectItem::ExprWithAlias { + expr: *right, + alias, + }) + } expr => self .parse_optional_alias(keywords::RESERVED_FOR_COLUMN_ALIAS) .map(|alias| match alias { diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs index 55ab3ddc3..55725eeca 100644 --- a/tests/sqlparser_common.rs +++ b/tests/sqlparser_common.rs @@ -11432,3 +11432,20 @@ 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); + + let dialects = all_dialects_where(|d| !d.supports_eq_alias_assigment()); + let sql = r#"SELECT x = (a * b) FROM some_table"#; + let expected = r#"SELECT x = (a * b) FROM some_table"#; + let _ = dialects.one_statement_parses_to(sql, expected); +}