hive: add support for array<> (#491)

Signed-off-by: Maciej Obuchowski <obuchowski.maciej@gmail.com>

Co-authored-by: Andrew Lamb <andrew@nerdnetworks.org>
This commit is contained in:
Maciej Obuchowski 2022-05-22 21:38:24 +02:00 committed by GitHub
parent 74f92079ac
commit 7ab30d95b0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 60 additions and 3 deletions

View file

@ -2700,6 +2700,15 @@ impl<'a> Parser<'a> {
}
Keyword::ENUM => Ok(DataType::Enum(self.parse_string_values()?)),
Keyword::SET => Ok(DataType::Set(self.parse_string_values()?)),
Keyword::ARRAY => {
// Hive array syntax. Note that nesting arrays - or other Hive syntax
// that ends with > will fail due to "C++" problem - >> is parsed as
// Token::ShiftRight
self.expect_token(&Token::Lt)?;
let inside_type = self.parse_data_type()?;
self.expect_token(&Token::Gt)?;
Ok(DataType::Array(Box::new(inside_type)))
}
_ => {
self.prev_token();
let type_name = self.parse_object_name()?;
@ -2709,7 +2718,8 @@ impl<'a> Parser<'a> {
unexpected => self.expected("a data type name", unexpected),
}?;
// Parse array data types. Note: this is postgresql-specific
// Parse array data types. Note: this is postgresql-specific and different from
// Keyword::ARRAY syntax from above
while self.consume_token(&Token::LBracket) {
self.expect_token(&Token::RBracket)?;
data = DataType::Array(Box::new(data))

View file

@ -23,8 +23,8 @@ mod test_utils;
use matches::assert_matches;
use sqlparser::ast::*;
use sqlparser::dialect::{
AnsiDialect, BigQueryDialect, GenericDialect, MsSqlDialect, PostgreSqlDialect, SQLiteDialect,
SnowflakeDialect,
AnsiDialect, BigQueryDialect, GenericDialect, HiveDialect, MsSqlDialect, PostgreSqlDialect,
SQLiteDialect, SnowflakeDialect,
};
use sqlparser::keywords::ALL_KEYWORDS;
use sqlparser::parser::{Parser, ParserError};
@ -1755,6 +1755,53 @@ fn parse_create_table() {
.contains("Expected constraint details after CONSTRAINT <name>"));
}
#[test]
fn parse_create_table_hive_array() {
// Parsing [] type arrays does not work in MsSql since [ is used in is_delimited_identifier_start
let dialects = TestedDialects {
dialects: vec![Box::new(PostgreSqlDialect {}), Box::new(HiveDialect {})],
};
let sql = "CREATE TABLE IF NOT EXISTS something (key int, val array<int>)";
match dialects.one_statement_parses_to(
sql,
"CREATE TABLE IF NOT EXISTS something (key INT, val INT[])",
) {
Statement::CreateTable {
if_not_exists,
name,
columns,
..
} => {
assert!(if_not_exists);
assert_eq!(name, ObjectName(vec!["something".into()]));
assert_eq!(
columns,
vec![
ColumnDef {
name: Ident::new("key"),
data_type: DataType::Int(None),
collation: None,
options: vec![],
},
ColumnDef {
name: Ident::new("val"),
data_type: DataType::Array(Box::new(DataType::Int(None))),
collation: None,
options: vec![],
},
],
)
}
_ => unreachable!(),
}
let res = parse_sql_statements("CREATE TABLE IF NOT EXISTS something (key int, val array<int)");
assert!(res
.unwrap_err()
.to_string()
.contains("Expected >, found: )"));
}
#[test]
fn parse_create_table_with_multiple_on_delete_in_constraint_fails() {
parse_sql_statements(