Skip to content

Commit a28bbcd

Browse files
authored
Allow array to be used as a function name again (#432)
* Allow `array` to be used as a function * clarify code, add docstrings * fix docs * cleanup * fmt
1 parent 3f56194 commit a28bbcd

File tree

3 files changed

+31
-17
lines changed

3 files changed

+31
-17
lines changed

src/ast/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,8 +159,13 @@ impl fmt::Display for ObjectName {
159159

160160
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
161161
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
162+
/// Represents an Array Expression, either
163+
/// `ARRAY[..]`, or `[..]`
162164
pub struct Array {
165+
/// The list of expressions between brackets
163166
pub elem: Vec<Expr>,
167+
168+
/// `true` for `ARRAY[..]`, `false` for `[..]`
164169
pub named: bool,
165170
}
166171

src/parser.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,11 @@ impl<'a> Parser<'a> {
420420
Keyword::TRIM => self.parse_trim_expr(),
421421
Keyword::INTERVAL => self.parse_literal_interval(),
422422
Keyword::LISTAGG => self.parse_listagg_expr(),
423-
Keyword::ARRAY => self.parse_array_expr(true),
423+
// Treat ARRAY[1,2,3] as an array [1,2,3], otherwise try as function call
424+
Keyword::ARRAY if self.peek_token() == Token::LBracket => {
425+
self.expect_token(&Token::LBracket)?;
426+
self.parse_array_expr(true)
427+
}
424428
Keyword::NOT => Ok(Expr::UnaryOp {
425429
op: UnaryOperator::Not,
426430
expr: Box::new(self.parse_subexpr(Self::UNARY_NOT_PREC)?),
@@ -450,6 +454,7 @@ impl<'a> Parser<'a> {
450454
_ => Ok(Expr::Identifier(w.to_ident())),
451455
},
452456
}, // End of Token::Word
457+
// array `[1, 2, 3]`
453458
Token::LBracket => self.parse_array_expr(false),
454459
tok @ Token::Minus | tok @ Token::Plus => {
455460
let op = if tok == Token::Plus {
@@ -826,10 +831,9 @@ impl<'a> Parser<'a> {
826831
}
827832
}
828833

834+
/// Parses an array expression `[ex1, ex2, ..]`
835+
/// if `named` is `true`, came from an expression like `ARRAY[ex1, ex2]`
829836
pub fn parse_array_expr(&mut self, named: bool) -> Result<Expr, ParserError> {
830-
if named {
831-
self.expect_token(&Token::LBracket)?;
832-
}
833837
let exprs = self.parse_comma_separated(Parser::parse_expr)?;
834838
self.expect_token(&Token::RBracket)?;
835839
Ok(Expr::Array(Array { elem: exprs, named }))

tests/sqlparser_common.rs

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2246,19 +2246,24 @@ fn parse_bad_constraint() {
22462246

22472247
#[test]
22482248
fn parse_scalar_function_in_projection() {
2249-
let sql = "SELECT sqrt(id) FROM foo";
2250-
let select = verified_only_select(sql);
2251-
assert_eq!(
2252-
&Expr::Function(Function {
2253-
name: ObjectName(vec![Ident::new("sqrt")]),
2254-
args: vec![FunctionArg::Unnamed(FunctionArgExpr::Expr(
2255-
Expr::Identifier(Ident::new("id"))
2256-
))],
2257-
over: None,
2258-
distinct: false,
2259-
}),
2260-
expr_from_projection(only(&select.projection))
2261-
);
2249+
let names = vec!["sqrt", "array", "foo"];
2250+
2251+
for function_name in names {
2252+
// like SELECT sqrt(id) FROM foo
2253+
let sql = dbg!(format!("SELECT {}(id) FROM foo", function_name));
2254+
let select = verified_only_select(&sql);
2255+
assert_eq!(
2256+
&Expr::Function(Function {
2257+
name: ObjectName(vec![Ident::new(function_name)]),
2258+
args: vec![FunctionArg::Unnamed(FunctionArgExpr::Expr(
2259+
Expr::Identifier(Ident::new("id"))
2260+
))],
2261+
over: None,
2262+
distinct: false,
2263+
}),
2264+
expr_from_projection(only(&select.projection))
2265+
);
2266+
}
22622267
}
22632268

22642269
fn run_explain_analyze(query: &str, expected_verbose: bool, expected_analyze: bool) {

0 commit comments

Comments
 (0)