Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions grammars/prql-lezer/src/prql.grammar
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ testInner { binaryTest | unaryTest | expression }
binaryTest[@name="BinaryExpression"] {
testInner !or LogicOp<"||" | "??"> testInner |
testInner !and LogicOp<"&&"> testInner |
testInner !compare (CompareOp<"==" | "!=" | "~=" | ">=" | "<=" | ">" | "<"> | kw<"in">) testInner
testInner !compare (CompareOp<"==" | "!=" | "~=" | "===" | "!==" | ">=" | "<=" | ">" | "<"> | kw<"in">) testInner
}

unaryTest[@name="UnaryExpression"] { kw<"!"> testInner }
Expand Down Expand Up @@ -100,7 +100,7 @@ ParenthesizedExpression { "(" expression ")" }

UnaryExpression {
!prefix ArithOp<"+" | "-"> expression |
!prefix CompareOp<"=="> Identifier
!prefix CompareOp<"==" | "==="> Identifier
}

// Because this is outside tokens, we can't disallow whitespace.
Expand Down
15 changes: 15 additions & 0 deletions prqlc/prqlc-parser/src/lexer/lr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ pub enum TokenKind {
ArrowFat, // =>
Eq, // ==
Ne, // !=
SEq, // ===
SNe, // !==
Gte, // >=
Lte, // <=
RegexSearch, // ~=
Expand Down Expand Up @@ -90,6 +92,17 @@ pub enum Literal {
ValueAndUnit(ValueAndUnit),
}

impl Literal {
// FIXME: Should it be a `null_safe_eq`, with `PartialEq` implementing
// 3VAL logic instead? This requires manual `PartialEq` implementation.
pub fn three_val_eq(&self, other: &Self) -> bool {
match (self, other) {
(Self::Null, Self::Null) => false,
_ => self == other,
}
}
}

impl TokenKind {
pub fn range(bind_left: bool, bind_right: bool) -> Self {
TokenKind::Range {
Expand Down Expand Up @@ -197,6 +210,8 @@ impl std::fmt::Display for TokenKind {
TokenKind::ArrowFat => f.write_str("=>"),
TokenKind::Eq => f.write_str("=="),
TokenKind::Ne => f.write_str("!="),
TokenKind::SEq => f.write_str("==="),
TokenKind::SNe => f.write_str("!=="),
TokenKind::Gte => f.write_str(">="),
TokenKind::Lte => f.write_str("<="),
TokenKind::RegexSearch => f.write_str("~="),
Expand Down
2 changes: 2 additions & 0 deletions prqlc/prqlc-parser/src/lexer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ fn lex_token() -> impl Parser<char, Token, Error = Cheap<char>> {
let control_multi = choice((
just("->").to(TokenKind::ArrowThin),
just("=>").to(TokenKind::ArrowFat),
just("===").to(TokenKind::SEq),
just("!==").to(TokenKind::SNe),
just("==").to(TokenKind::Eq),
just("!=").to(TokenKind::Ne),
just(">=").to(TokenKind::Gte),
Expand Down
3 changes: 3 additions & 0 deletions prqlc/prqlc-parser/src/parser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,7 @@ fn operator_unary() -> impl Parser<TokenKind, UnOp, Error = PError> + Clone {
.or(ctrl('-').to(UnOp::Neg))
.or(ctrl('!').to(UnOp::Not))
.or(just(TokenKind::Eq).to(UnOp::EqSelf))
.or(just(TokenKind::SEq).to(UnOp::SEqSelf))
}
fn operator_pow() -> impl Parser<TokenKind, BinOp, Error = PError> + Clone {
just(TokenKind::Pow).to(BinOp::Pow)
Expand All @@ -560,6 +561,8 @@ fn operator_compare() -> impl Parser<TokenKind, BinOp, Error = PError> + Clone {
choice((
just(TokenKind::Eq).to(BinOp::Eq),
just(TokenKind::Ne).to(BinOp::Ne),
just(TokenKind::SEq).to(BinOp::SEq),
just(TokenKind::SNe).to(BinOp::SNe),
just(TokenKind::Lte).to(BinOp::Lte),
just(TokenKind::Gte).to(BinOp::Gte),
just(TokenKind::RegexSearch).to(BinOp::RegexSearch),
Expand Down
6 changes: 6 additions & 0 deletions prqlc/prqlc-parser/src/parser/pr/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ pub enum UnOp {
Not,
#[strum(to_string = "==")]
EqSelf,
#[strum(to_string = "===")]
SEqSelf,
}

#[derive(
Expand Down Expand Up @@ -57,6 +59,10 @@ pub enum BinOp {
Eq,
#[strum(to_string = "!=")]
Ne,
#[strum(to_string = "===")]
SEq,
#[strum(to_string = "!==")]
SNe,
#[strum(to_string = ">")]
Gt,
#[strum(to_string = "<")]
Expand Down
2 changes: 2 additions & 0 deletions prqlc/prqlc/src/cli/highlight.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ fn highlight_token_kind(token: &TokenKind) -> String {
| TokenKind::ArrowFat
| TokenKind::Eq
| TokenKind::Ne
| TokenKind::SEq
| TokenKind::SNe
| TokenKind::Gte
| TokenKind::Lte
| TokenKind::RegexSearch => output.push_str(&format!("{}", token)),
Expand Down
2 changes: 2 additions & 0 deletions prqlc/prqlc/src/codegen/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,8 @@ fn binding_strength(expr: &pr::ExprKind) -> u8 {
pr::BinOp::Add | pr::BinOp::Sub => 17,
pr::BinOp::Eq
| pr::BinOp::Ne
| pr::BinOp::SEq
| pr::BinOp::SNe
| pr::BinOp::Gt
| pr::BinOp::Lt
| pr::BinOp::Gte
Expand Down
8 changes: 6 additions & 2 deletions prqlc/prqlc/src/semantic/ast_expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,9 @@ fn expand_unary(pr::UnaryExpr { op, expr }: pr::UnaryExpr) -> Result<pl::ExprKin
Neg => ["std", "neg"],
Not => ["std", "not"],
Add => return Ok(expr.kind),
EqSelf => {
EqSelf | SEqSelf => {
let method = if op == EqSelf { "eq" } else { "seq" };

let pl::ExprKind::Ident(ident) = expr.kind else {
return Err(Error::new_simple(
"you can only use column names with self-equality operator",
Expand All @@ -188,7 +190,7 @@ fn expand_unary(pr::UnaryExpr { op, expr }: pr::UnaryExpr) -> Result<pl::ExprKin
name: ident.name,
})
};
return Ok(new_binop(left, &["std", "eq"], right).kind);
return Ok(new_binop(left, &["std", method], right).kind);
}
};
Ok(pl::ExprKind::FuncCall(pl::FuncCall::new_simple(
Expand All @@ -212,6 +214,8 @@ fn expand_binary(pr::BinaryExpr { op, left, right }: pr::BinaryExpr) -> Result<p
pr::BinOp::Sub => vec!["std", "sub"],
pr::BinOp::Eq => vec!["std", "eq"],
pr::BinOp::Ne => vec!["std", "ne"],
pr::BinOp::SEq => vec!["std", "seq"],
pr::BinOp::SNe => vec!["std", "sne"],
pr::BinOp::Gt => vec!["std", "gt"],
pr::BinOp::Lt => vec!["std", "lt"],
pr::BinOp::Gte => vec!["std", "gte"],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,27 @@ columns:
name:
- orders
- customer_no
target_id: 123
target_id: 125
target_name: ~
- Single:
name:
- orders
- gross
target_id: 124
target_id: 126
target_name: ~
- Single:
name:
- orders
- tax
target_id: 125
target_id: 127
target_name: ~
- Single:
name: ~
target_id: 126
target_id: 128
target_name: ~
inputs:
- id: 121
- id: 123
name: orders
table:
- default_db
- orders

Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ expression: "resolve_derive(r#\"\n from a\n derive one = (
kind:
Array:
kind: Any
span: "0:1929-1936"
span: "0:2025-2032"
name: ~
span: "0:1928-1937"
span: "0:2024-2033"
name: array
span: "1:52-55"
alias: one
Expand All @@ -26,12 +26,12 @@ expression: "resolve_derive(r#\"\n from a\n derive one = (
- - ~
- kind:
Primitive: Int
span: "0:4123-4126"
span: "0:4219-4222"
name: ~
- - ~
- kind:
Primitive: Float
span: "0:4130-4135"
span: "0:4226-4231"
name: ~
span: "0:4123-4135"
span: "0:4219-4231"
name: ~
Loading