PostgreSQL: unary minus binds more loosely than `^`, so `-1 ^ 0` parses as `-(1 ^ 0)`
Mantenedores costumam responder em até 1 dia
Ninguém assumiu esta issue ainda.
- #2830 de @compiler-segfault — fechado sem integrar
Avaliação
- Dificuldade
- 3/5
- Tempo estimado
- 1-2 dias
- Facilidade para iniciantes
- 72/100
- Tipo de issue
- Bug
- Clareza
- Claramente especificada
- Status de atividade
- Ativa
- Stack de tecnologia
- rust
- Domínio
- backend-api-design
Direção de pesquisa
Read parse_prefix_inner in src/parser/mod.rs and the precedence constants in src/dialect/postgresql.rs; compare the PostgreSQL precedence table cited in the issue. Add or adjust parser coverage for unary plus and minus with ^, including the reproduced expressions. Done means the PostgreSQL dialect produces the expected AST grouping while the generic dialect remains unaffected.
Escrita pelo modelo de indexação a partir do texto da issue.
Descrição
Problem
In PostgreSqlDialect, a unary minus binds more loosely than ^. The parser reads -1 ^ 0 as -(1 ^ 0).
In PostgreSQL, unary minus binds more tightly than ^ (operator precedence table). PostgreSQL reads -1 ^ 0 as (-1) ^ 0.
Reproduction
At main (d1c1790e3):
use sqlparser::dialect::PostgreSqlDialect;
use sqlparser::parser::Parser;
let ast = Parser::parse_sql(&PostgreSqlDialect {}, "SELECT -1 ^ 0").unwrap();
println!("{ast:#?}");
The projection expression is (spans removed):
UnaryOp {
op: Minus,
expr: BinaryOp {
left: Value(Number("1", false)),
op: PGExp,
right: Value(Number("0", false)),
},
}
The expected expression is:
BinaryOp {
left: UnaryOp { op: Minus, expr: Value(Number("1", false)) },
op: PGExp,
right: Value(Number("0", false)),
}
SELECT -2 ^ 2 and SELECT +2 ^ 2 parse the same way.
Effect on query results
The grouping changes the result:
| Query | PostgreSQL 17 | DuckDB | DataFusion (PostgreSQL dialect) |
|---|---|---|---|
SELECT -1 ^ 0 |
1 | 1 | -1 |
SELECT -2 ^ 2 |
4 | 4 | -4 |
DataFusion tracks this in apache/datafusion#27094.
Cause
parse_prefix_inner parses the operand of a unary - or + at Precedence::MulDivModOp (src/parser/mod.rs#L1967-L1979):
tok @ Token::Minus | tok @ Token::Plus => {
// ...
Ok(Expr::UnaryOp {
op,
expr: Box::new(
self.parse_subexpr(self.dialect.prec_value(Precedence::MulDivModOp))?,
),
})
}
PostgreSqlDialect sets CARET_PREC (100) above MUL_DIV_MOD_OP_PREC (90) (src/dialect/postgresql.rs#L213-L214). So the operand of the minus also takes the ^ that follows.
For the PostgreSQL dialect, the operand of a unary - or + must be parsed at a precedence above CARET_PREC. In the PostgreSQL table, unary + and - are also above COLLATE and AT.
The generic dialect is not affected in this way: there, Caret is below MulDivModOp.
Related: #814 (precedence of ~).
- Linguagem predominante
- Rust
- Estrelas
- 3.5k
- Forks
- 805
- Merge médio
- 2d 3h
- PRs com merge (30d)
- 116
Preparar o ambiente
- Sem Dockerfile nem arquivo Docker Compose
- Tem um modelo de pull request
- Sem guia de contribuição
Primeiros passos
- Leia a issue inteira e depois o guia de contribuição do projeto.
- Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
- Faça um fork do repositório e trabalhe em uma branch.
- Abra um pull request que referencie o número da issue.
Mais de apache/datafusion-sqlparser-rs
-
Redshift
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 82/100
apache/datafusion-sqlparser-rs#2959 ·
Mantenedores costumam responder em até 1 dia
-
Redshift
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 68/100
apache/datafusion-sqlparser-rs#2958 ·
Mantenedores costumam responder em até 1 dia
-
PostgreSQL
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 76/100
apache/datafusion-sqlparser-rs#2862 ·
Mantenedores costumam responder em até 1 dia
-
PostgreSQL
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 75/100
apache/datafusion-sqlparser-rs#2861 ·
Mantenedores costumam responder em até 1 dia
-
PostgreSQL
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 77/100
apache/datafusion-sqlparser-rs#2858 ·
Mantenedores costumam responder em até 1 dia
Todas as issues de apache/datafusion-sqlparser-rs
Issues semelhantes
-
P3
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 70/100
HerringtonDarkholme/hd-lang#1770 ·
Mantenedores costumam responder em até 1 dia
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 82/100
jonathanong/no-mistakes#3332 ·
Mantenedores costumam responder em até 1 dia
-
bug
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 78/100
swc-project/swc-next-issues#310 ·
-
bug
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 72/100
swc-project/swc-ai-issues#653 ·
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 72/100
lbjlaq/Antigravity-Manager#3937 ·
Mantenedores costumam responder em até 1 dia