mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-08-21 14:40:18 +00:00
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:
parent
0d6386e4a3
commit
1da49c15c7
3 changed files with 107 additions and 46 deletions
|
@ -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> {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue