diff --git a/src/ast/mod.rs b/src/ast/mod.rs index 20058b83a..b6d67df5b 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -1964,6 +1964,7 @@ impl fmt::Display for Expr { | UnaryOperator::Hash | UnaryOperator::AtDashAt | UnaryOperator::DoubleAt + | UnaryOperator::PGAbs | UnaryOperator::QuestionDash | UnaryOperator::QuestionPipe ) { diff --git a/tests/sqlparser_postgres.rs b/tests/sqlparser_postgres.rs index d71e49b27..c85cb26fa 100644 --- a/tests/sqlparser_postgres.rs +++ b/tests/sqlparser_postgres.rs @@ -2623,13 +2623,13 @@ fn parse_ampersand_arobase() { #[test] fn parse_pg_unary_ops() { let pg_unary_ops = &[ - ("|/", UnaryOperator::PGSquareRoot), - ("||/", UnaryOperator::PGCubeRoot), - ("!!", UnaryOperator::PGPrefixFactorial), - ("@", UnaryOperator::PGAbs), + ("SELECT |/a", UnaryOperator::PGSquareRoot), + ("SELECT ||/a", UnaryOperator::PGCubeRoot), + ("SELECT !!a", UnaryOperator::PGPrefixFactorial), + ("SELECT @ a", UnaryOperator::PGAbs), ]; - for (str_op, op) in pg_unary_ops { - let select = pg().verified_only_select(&format!("SELECT {}a", str_op)); + for (sql, op) in pg_unary_ops { + let select = pg().verified_only_select(sql); assert_eq!( SelectItem::UnnamedExpr(Expr::UnaryOp { op: *op, @@ -9953,3 +9953,18 @@ fn parse_insert_by_name_keywords_as_table_and_alias() { statement => panic!("Expected INSERT statement, got: {statement:?}"), } } + +#[test] +fn parse_pg_abs_space_before_negative_operand() { + // `@-` tokenizes as a geometric operator prefix, so displaying PGAbs + // without a space breaks re-parsing of a negative operand. + pg().verified_stmt("SELECT @ -2"); + pg().one_statement_parses_to("SELECT @a", "SELECT @ a"); + let err = pg().parse_sql_statements("SELECT @-2").unwrap_err(); + assert_eq!( + ParserError::TokenizerError( + "Expected a valid binary operator after '@-' at Line: 1, Column: 10".to_string(), + ), + err + ); +}