Support array expressions such as ARRAY[1,2] , foo[1] and INT[][] (#419)

* feat: add array expression

* test: add back the the existing test

Co-authored-by: gamife <gamife9886@gmail.com>
This commit is contained in:
gamife 2022-02-17 20:21:11 +08:00 committed by GitHub
parent 0d6386e4a3
commit 1da49c15c7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 107 additions and 46 deletions

View file

@ -420,6 +420,7 @@ impl<'a> Parser<'a> {
Keyword::TRIM => self.parse_trim_expr(),
Keyword::INTERVAL => self.parse_literal_interval(),
Keyword::LISTAGG => self.parse_listagg_expr(),
Keyword::ARRAY => self.parse_array_expr(),
Keyword::NOT => Ok(Expr::UnaryOp {
op: UnaryOperator::Not,
expr: Box::new(self.parse_subexpr(Self::UNARY_NOT_PREC)?),
@ -820,6 +821,13 @@ impl<'a> Parser<'a> {
}
}
pub fn parse_array_expr(&mut self) -> Result<Expr, ParserError> {
self.expect_token(&Token::LBracket)?;
let exprs = self.parse_comma_separated(Parser::parse_expr)?;
self.expect_token(&Token::RBracket)?;
Ok(Expr::Array(exprs))
}
/// Parse a SQL LISTAGG expression, e.g. `LISTAGG(...) WITHIN GROUP (ORDER BY ...)`.
pub fn parse_listagg_expr(&mut self) -> Result<Expr, ParserError> {
self.expect_token(&Token::LParen)?;
@ -1083,6 +1091,10 @@ impl<'a> Parser<'a> {
expr: Box::new(expr),
})
} else if Token::LBracket == tok {
if dialect_of!(self is PostgreSqlDialect) {
// parse index
return self.parse_array_index(expr);
}
self.parse_map_access(expr)
} else {
// Can only happen if `get_next_precedence` got out of sync with this function
@ -1090,6 +1102,21 @@ impl<'a> Parser<'a> {
}
}
pub fn parse_array_index(&mut self, expr: Expr) -> Result<Expr, ParserError> {
let index = self.parse_expr()?;
self.expect_token(&Token::RBracket)?;
let mut indexs: Vec<Expr> = vec![index];
while self.consume_token(&Token::LBracket) {
let index = self.parse_expr()?;
self.expect_token(&Token::RBracket)?;
indexs.push(index);
}
Ok(Expr::ArrayIndex {
obj: Box::new(expr),
indexs,
})
}
pub fn parse_map_access(&mut self, expr: Expr) -> Result<Expr, ParserError> {
let key = self.parse_map_key()?;
let tok = self.consume_token(&Token::RBracket);
@ -1202,7 +1229,7 @@ impl<'a> Parser<'a> {
Token::Mul | Token::Div | Token::Mod | Token::StringConcat => Ok(40),
Token::DoubleColon => Ok(50),
Token::ExclamationMark => Ok(50),
Token::LBracket | Token::RBracket => Ok(10),
Token::LBracket => Ok(10),
_ => Ok(0),
}
}
@ -2287,7 +2314,7 @@ impl<'a> Parser<'a> {
/// Parse a SQL datatype (in the context of a CREATE TABLE statement for example)
pub fn parse_data_type(&mut self) -> Result<DataType, ParserError> {
match self.next_token() {
let mut data = match self.next_token() {
Token::Word(w) => match w.keyword {
Keyword::BOOLEAN => Ok(DataType::Boolean),
Keyword::FLOAT => Ok(DataType::Float(self.parse_optional_precision()?)),
@ -2332,15 +2359,7 @@ impl<'a> Parser<'a> {
Keyword::INTERVAL => Ok(DataType::Interval),
Keyword::REGCLASS => Ok(DataType::Regclass),
Keyword::STRING => Ok(DataType::String),
Keyword::TEXT => {
if self.consume_token(&Token::LBracket) {
// Note: this is postgresql-specific
self.expect_token(&Token::RBracket)?;
Ok(DataType::Array(Box::new(DataType::Text)))
} else {
Ok(DataType::Text)
}
}
Keyword::TEXT => Ok(DataType::Text),
Keyword::BYTEA => Ok(DataType::Bytea),
Keyword::NUMERIC | Keyword::DECIMAL | Keyword::DEC => {
let (precision, scale) = self.parse_optional_precision_scale()?;
@ -2355,7 +2374,14 @@ impl<'a> Parser<'a> {
}
},
unexpected => self.expected("a data type name", unexpected),
}?;
// Parse array data types. Note: this is postgresql-specific
while self.consume_token(&Token::LBracket) {
self.expect_token(&Token::RBracket)?;
data = DataType::Array(Box::new(data))
}
Ok(data)
}
pub fn parse_string_values(&mut self) -> Result<Vec<String>, ParserError> {