feat: support = operator in function args (#1128)

Co-authored-by: Andrew Lamb <andrew@nerdnetworks.org>
This commit is contained in:
universalmind303 2024-02-08 19:24:42 -06:00 committed by GitHub
parent 6245231479
commit d981b0996a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 82 additions and 3 deletions

View file

@ -4287,18 +4287,46 @@ impl fmt::Display for FunctionArgExpr {
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
/// Operator used to separate function arguments
pub enum FunctionArgOperator {
/// function(arg1 = value1)
Equals,
/// function(arg1 => value1)
RightArrow,
}
impl fmt::Display for FunctionArgOperator {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
FunctionArgOperator::Equals => f.write_str("="),
FunctionArgOperator::RightArrow => f.write_str("=>"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum FunctionArg {
Named { name: Ident, arg: FunctionArgExpr },
Named {
name: Ident,
arg: FunctionArgExpr,
operator: FunctionArgOperator,
},
Unnamed(FunctionArgExpr),
}
impl fmt::Display for FunctionArg {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
FunctionArg::Named { name, arg } => write!(f, "{name} => {arg}"),
FunctionArg::Named {
name,
arg,
operator,
} => write!(f, "{name} {operator} {arg}"),
FunctionArg::Unnamed(unnamed_arg) => write!(f, "{unnamed_arg}"),
}
}

View file

@ -8106,7 +8106,22 @@ impl<'a> Parser<'a> {
self.expect_token(&Token::RArrow)?;
let arg = self.parse_wildcard_expr()?.into();
Ok(FunctionArg::Named { name, arg })
Ok(FunctionArg::Named {
name,
arg,
operator: FunctionArgOperator::RightArrow,
})
} else if self.peek_nth_token(1) == Token::Eq {
let name = self.parse_identifier(false)?;
self.expect_token(&Token::Eq)?;
let arg = self.parse_wildcard_expr()?.into();
Ok(FunctionArg::Named {
name,
arg,
operator: FunctionArgOperator::Equals,
})
} else {
Ok(FunctionArg::Unnamed(self.parse_wildcard_expr()?.into()))
}

View file

@ -3971,12 +3971,48 @@ fn parse_named_argument_function() {
arg: FunctionArgExpr::Expr(Expr::Value(Value::SingleQuotedString(
"1".to_owned()
))),
operator: FunctionArgOperator::RightArrow
},
FunctionArg::Named {
name: Ident::new("b"),
arg: FunctionArgExpr::Expr(Expr::Value(Value::SingleQuotedString(
"2".to_owned()
))),
operator: FunctionArgOperator::RightArrow
},
],
null_treatment: None,
filter: None,
over: None,
distinct: false,
special: false,
order_by: vec![],
}),
expr_from_projection(only(&select.projection))
);
}
#[test]
fn parse_named_argument_function_with_eq_operator() {
let sql = "SELECT FUN(a = '1', b = '2') FROM foo";
let select = verified_only_select(sql);
assert_eq!(
&Expr::Function(Function {
name: ObjectName(vec![Ident::new("FUN")]),
args: vec![
FunctionArg::Named {
name: Ident::new("a"),
arg: FunctionArgExpr::Expr(Expr::Value(Value::SingleQuotedString(
"1".to_owned()
))),
operator: FunctionArgOperator::Equals
},
FunctionArg::Named {
name: Ident::new("b"),
arg: FunctionArgExpr::Expr(Expr::Value(Value::SingleQuotedString(
"2".to_owned()
))),
operator: FunctionArgOperator::Equals
},
],
null_treatment: None,