Skip to content

Commit 25e01ac

Browse files
Fix unary minus rendering into -- line comments
1 parent 1195239 commit 25e01ac

3 files changed

Lines changed: 37 additions & 1 deletion

File tree

src/ast/mod.rs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1966,7 +1966,8 @@ impl fmt::Display for Expr {
19661966
| UnaryOperator::DoubleAt
19671967
| UnaryOperator::QuestionDash
19681968
| UnaryOperator::QuestionPipe
1969-
) {
1969+
) || (op == &UnaryOperator::Minus && starts_with_operator_char(expr))
1970+
{
19701971
write!(f, "{op} {expr}")
19711972
} else {
19721973
write!(f, "{op}{expr}")
@@ -8083,6 +8084,26 @@ impl fmt::Display for FunctionArg {
80838084
}
80848085
}
80858086

8087+
/// Whether `expr` renders with an operator character first. A prefix `-`
8088+
/// must not abut one, since `--` starts a line comment and operator-run
8089+
/// dialects fuse `-@`, `-~`, `-#`, `-!!` and `-||/` into single tokens.
8090+
fn starts_with_operator_char(expr: &Expr) -> bool {
8091+
use fmt::Write;
8092+
struct FirstChar(Option<char>);
8093+
impl fmt::Write for FirstChar {
8094+
fn write_str(&mut self, s: &str) -> fmt::Result {
8095+
if self.0.is_none() {
8096+
self.0 = s.chars().next();
8097+
}
8098+
Ok(())
8099+
}
8100+
}
8101+
let mut first = FirstChar(None);
8102+
let _ = write!(first, "{expr}");
8103+
const OPERATOR_CHARS: &str = "+-*/<>=~!@%#^&|";
8104+
first.0.is_some_and(|c| OPERATOR_CHARS.contains(c))
8105+
}
8106+
80868107
/// `FunctionArgOperator::Space` has no token of its own, so the name and the
80878108
/// value are separated by a single space instead.
80888109
fn fmt_named_function_arg(

tests/sqlparser_common.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20060,3 +20060,11 @@ fn parse_insert_by_name() {
2006020060
_ => unreachable!(),
2006120061
}
2006220062
}
20063+
20064+
#[test]
20065+
fn parse_unary_minus_never_renders_line_comment() {
20066+
all_dialects().verified_stmt("SELECT - -1");
20067+
all_dialects().verified_stmt("SELECT - - -1");
20068+
all_dialects().verified_stmt("SELECT -1");
20069+
all_dialects().verified_stmt("SELECT -x");
20070+
}

tests/sqlparser_postgres.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9953,3 +9953,10 @@ fn parse_insert_by_name_keywords_as_table_and_alias() {
99539953
statement => panic!("Expected INSERT statement, got: {statement:?}"),
99549954
}
99559955
}
9956+
9957+
#[test]
9958+
fn parse_unary_minus_before_pg_prefix_operators() {
9959+
pg().verified_stmt("SELECT - ~1");
9960+
pg().verified_stmt("SELECT - @2");
9961+
pg().one_statement_parses_to("SELECT - #x", "SELECT - # x");
9962+
}

0 commit comments

Comments
 (0)