mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-08-22 15:04:04 +00:00
Support the ARRAY type of Snowflake (#699)
* Snowflake Array * Use the array data type * Try to fix build * Try to fix build * Change Array to option * Remove unused import
This commit is contained in:
parent
bbf32a9e81
commit
0f7e144890
5 changed files with 52 additions and 21 deletions
|
@ -141,7 +141,7 @@ pub enum DataType {
|
||||||
/// Custom type such as enums
|
/// Custom type such as enums
|
||||||
Custom(ObjectName, Vec<String>),
|
Custom(ObjectName, Vec<String>),
|
||||||
/// Arrays
|
/// Arrays
|
||||||
Array(Box<DataType>),
|
Array(Option<Box<DataType>>),
|
||||||
/// Enums
|
/// Enums
|
||||||
Enum(Vec<String>),
|
Enum(Vec<String>),
|
||||||
/// Set
|
/// Set
|
||||||
|
@ -232,7 +232,13 @@ impl fmt::Display for DataType {
|
||||||
DataType::Text => write!(f, "TEXT"),
|
DataType::Text => write!(f, "TEXT"),
|
||||||
DataType::String => write!(f, "STRING"),
|
DataType::String => write!(f, "STRING"),
|
||||||
DataType::Bytea => write!(f, "BYTEA"),
|
DataType::Bytea => write!(f, "BYTEA"),
|
||||||
DataType::Array(ty) => write!(f, "{}[]", ty),
|
DataType::Array(ty) => {
|
||||||
|
if let Some(t) = &ty {
|
||||||
|
write!(f, "{}[]", t)
|
||||||
|
} else {
|
||||||
|
write!(f, "ARRAY")
|
||||||
|
}
|
||||||
|
}
|
||||||
DataType::Custom(ty, modifiers) => {
|
DataType::Custom(ty, modifiers) => {
|
||||||
if modifiers.is_empty() {
|
if modifiers.is_empty() {
|
||||||
write!(f, "{}", ty)
|
write!(f, "{}", ty)
|
||||||
|
|
|
@ -3672,13 +3672,17 @@ impl<'a> Parser<'a> {
|
||||||
Keyword::ENUM => Ok(DataType::Enum(self.parse_string_values()?)),
|
Keyword::ENUM => Ok(DataType::Enum(self.parse_string_values()?)),
|
||||||
Keyword::SET => Ok(DataType::Set(self.parse_string_values()?)),
|
Keyword::SET => Ok(DataType::Set(self.parse_string_values()?)),
|
||||||
Keyword::ARRAY => {
|
Keyword::ARRAY => {
|
||||||
// Hive array syntax. Note that nesting arrays - or other Hive syntax
|
if dialect_of!(self is SnowflakeDialect) {
|
||||||
// that ends with > will fail due to "C++" problem - >> is parsed as
|
Ok(DataType::Array(None))
|
||||||
// Token::ShiftRight
|
} else {
|
||||||
self.expect_token(&Token::Lt)?;
|
// Hive array syntax. Note that nesting arrays - or other Hive syntax
|
||||||
let inside_type = self.parse_data_type()?;
|
// that ends with > will fail due to "C++" problem - >> is parsed as
|
||||||
self.expect_token(&Token::Gt)?;
|
// Token::ShiftRight
|
||||||
Ok(DataType::Array(Box::new(inside_type)))
|
self.expect_token(&Token::Lt)?;
|
||||||
|
let inside_type = self.parse_data_type()?;
|
||||||
|
self.expect_token(&Token::Gt)?;
|
||||||
|
Ok(DataType::Array(Some(Box::new(inside_type))))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
self.prev_token();
|
self.prev_token();
|
||||||
|
@ -3697,7 +3701,7 @@ impl<'a> Parser<'a> {
|
||||||
// Keyword::ARRAY syntax from above
|
// Keyword::ARRAY syntax from above
|
||||||
while self.consume_token(&Token::LBracket) {
|
while self.consume_token(&Token::LBracket) {
|
||||||
self.expect_token(&Token::RBracket)?;
|
self.expect_token(&Token::RBracket)?;
|
||||||
data = DataType::Array(Box::new(data))
|
data = DataType::Array(Some(Box::new(data)))
|
||||||
}
|
}
|
||||||
Ok(data)
|
Ok(data)
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ use sqlparser::ast::SelectItem::UnnamedExpr;
|
||||||
use sqlparser::ast::*;
|
use sqlparser::ast::*;
|
||||||
use sqlparser::dialect::{
|
use sqlparser::dialect::{
|
||||||
AnsiDialect, BigQueryDialect, ClickHouseDialect, GenericDialect, HiveDialect, MsSqlDialect,
|
AnsiDialect, BigQueryDialect, ClickHouseDialect, GenericDialect, HiveDialect, MsSqlDialect,
|
||||||
PostgreSqlDialect, SQLiteDialect, SnowflakeDialect,
|
MySqlDialect, PostgreSqlDialect, SQLiteDialect, SnowflakeDialect,
|
||||||
};
|
};
|
||||||
use sqlparser::keywords::ALL_KEYWORDS;
|
use sqlparser::keywords::ALL_KEYWORDS;
|
||||||
use sqlparser::parser::{Parser, ParserError};
|
use sqlparser::parser::{Parser, ParserError};
|
||||||
|
@ -2099,7 +2099,7 @@ fn parse_create_table_hive_array() {
|
||||||
},
|
},
|
||||||
ColumnDef {
|
ColumnDef {
|
||||||
name: Ident::new("val"),
|
name: Ident::new("val"),
|
||||||
data_type: DataType::Array(Box::new(DataType::Int(None))),
|
data_type: DataType::Array(Some(Box::new(DataType::Int(None)))),
|
||||||
collation: None,
|
collation: None,
|
||||||
options: vec![],
|
options: vec![],
|
||||||
},
|
},
|
||||||
|
@ -2109,12 +2109,20 @@ fn parse_create_table_hive_array() {
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
|
|
||||||
let res =
|
// SnowflakeDialect using array diffrent
|
||||||
parse_sql_statements("CREATE TABLE IF NOT EXISTS something (name int, val array<int)");
|
let dialects = TestedDialects {
|
||||||
assert!(res
|
dialects: vec![
|
||||||
.unwrap_err()
|
Box::new(PostgreSqlDialect {}),
|
||||||
.to_string()
|
Box::new(HiveDialect {}),
|
||||||
.contains("Expected >, found: )"));
|
Box::new(MySqlDialect {}),
|
||||||
|
],
|
||||||
|
};
|
||||||
|
let sql = "CREATE TABLE IF NOT EXISTS something (name int, val array<int)";
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
dialects.parse_sql_statements(sql).unwrap_err(),
|
||||||
|
ParserError::ParserError("Expected >, found: )".to_string())
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -1324,9 +1324,9 @@ fn parse_array_index_expr() {
|
||||||
})],
|
})],
|
||||||
named: true,
|
named: true,
|
||||||
})),
|
})),
|
||||||
data_type: DataType::Array(Box::new(DataType::Array(Box::new(DataType::Int(
|
data_type: DataType::Array(Some(Box::new(DataType::Array(Some(Box::new(
|
||||||
None
|
DataType::Int(None)
|
||||||
)))))
|
))))))
|
||||||
}))),
|
}))),
|
||||||
indexes: vec![num[1].clone(), num[2].clone()],
|
indexes: vec![num[1].clone(), num[2].clone()],
|
||||||
},
|
},
|
||||||
|
|
|
@ -143,6 +143,19 @@ fn test_single_table_in_parenthesis_with_alias() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_array() {
|
||||||
|
let sql = "SELECT CAST(a AS ARRAY) FROM customer";
|
||||||
|
let select = snowflake().verified_only_select(sql);
|
||||||
|
assert_eq!(
|
||||||
|
&Expr::Cast {
|
||||||
|
expr: Box::new(Expr::Identifier(Ident::new("a"))),
|
||||||
|
data_type: DataType::Array(None),
|
||||||
|
},
|
||||||
|
expr_from_projection(only(&select.projection))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_json_using_colon() {
|
fn parse_json_using_colon() {
|
||||||
let sql = "SELECT a:b FROM t";
|
let sql = "SELECT a:b FROM t";
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue