Skip to content

Commit 7ab30d9

Browse files
mobuchowskialamb
andauthored
hive: add support for array<> (apache#491)
Signed-off-by: Maciej Obuchowski <obuchowski.maciej@gmail.com> Co-authored-by: Andrew Lamb <andrew@nerdnetworks.org>
1 parent 74f9207 commit 7ab30d9

File tree

2 files changed

+60
-3
lines changed

2 files changed

+60
-3
lines changed

src/parser.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2700,6 +2700,15 @@ impl<'a> Parser<'a> {
27002700
}
27012701
Keyword::ENUM => Ok(DataType::Enum(self.parse_string_values()?)),
27022702
Keyword::SET => Ok(DataType::Set(self.parse_string_values()?)),
2703+
Keyword::ARRAY => {
2704+
// Hive array syntax. Note that nesting arrays - or other Hive syntax
2705+
// that ends with > will fail due to "C++" problem - >> is parsed as
2706+
// Token::ShiftRight
2707+
self.expect_token(&Token::Lt)?;
2708+
let inside_type = self.parse_data_type()?;
2709+
self.expect_token(&Token::Gt)?;
2710+
Ok(DataType::Array(Box::new(inside_type)))
2711+
}
27032712
_ => {
27042713
self.prev_token();
27052714
let type_name = self.parse_object_name()?;
@@ -2709,7 +2718,8 @@ impl<'a> Parser<'a> {
27092718
unexpected => self.expected("a data type name", unexpected),
27102719
}?;
27112720

2712-
// Parse array data types. Note: this is postgresql-specific
2721+
// Parse array data types. Note: this is postgresql-specific and different from
2722+
// Keyword::ARRAY syntax from above
27132723
while self.consume_token(&Token::LBracket) {
27142724
self.expect_token(&Token::RBracket)?;
27152725
data = DataType::Array(Box::new(data))

tests/sqlparser_common.rs

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ mod test_utils;
2323
use matches::assert_matches;
2424
use sqlparser::ast::*;
2525
use sqlparser::dialect::{
26-
AnsiDialect, BigQueryDialect, GenericDialect, MsSqlDialect, PostgreSqlDialect, SQLiteDialect,
27-
SnowflakeDialect,
26+
AnsiDialect, BigQueryDialect, GenericDialect, HiveDialect, MsSqlDialect, PostgreSqlDialect,
27+
SQLiteDialect, SnowflakeDialect,
2828
};
2929
use sqlparser::keywords::ALL_KEYWORDS;
3030
use sqlparser::parser::{Parser, ParserError};
@@ -1755,6 +1755,53 @@ fn parse_create_table() {
17551755
.contains("Expected constraint details after CONSTRAINT <name>"));
17561756
}
17571757

1758+
#[test]
1759+
fn parse_create_table_hive_array() {
1760+
// Parsing [] type arrays does not work in MsSql since [ is used in is_delimited_identifier_start
1761+
let dialects = TestedDialects {
1762+
dialects: vec![Box::new(PostgreSqlDialect {}), Box::new(HiveDialect {})],
1763+
};
1764+
let sql = "CREATE TABLE IF NOT EXISTS something (key int, val array<int>)";
1765+
match dialects.one_statement_parses_to(
1766+
sql,
1767+
"CREATE TABLE IF NOT EXISTS something (key INT, val INT[])",
1768+
) {
1769+
Statement::CreateTable {
1770+
if_not_exists,
1771+
name,
1772+
columns,
1773+
..
1774+
} => {
1775+
assert!(if_not_exists);
1776+
assert_eq!(name, ObjectName(vec!["something".into()]));
1777+
assert_eq!(
1778+
columns,
1779+
vec![
1780+
ColumnDef {
1781+
name: Ident::new("key"),
1782+
data_type: DataType::Int(None),
1783+
collation: None,
1784+
options: vec![],
1785+
},
1786+
ColumnDef {
1787+
name: Ident::new("val"),
1788+
data_type: DataType::Array(Box::new(DataType::Int(None))),
1789+
collation: None,
1790+
options: vec![],
1791+
},
1792+
],
1793+
)
1794+
}
1795+
_ => unreachable!(),
1796+
}
1797+
1798+
let res = parse_sql_statements("CREATE TABLE IF NOT EXISTS something (key int, val array<int)");
1799+
assert!(res
1800+
.unwrap_err()
1801+
.to_string()
1802+
.contains("Expected >, found: )"));
1803+
}
1804+
17581805
#[test]
17591806
fn parse_create_table_with_multiple_on_delete_in_constraint_fails() {
17601807
parse_sql_statements(

0 commit comments

Comments
 (0)