Skip to content

Commit 6f090e5

Browse files
adding delimited (#1155)
1 parent fb7d4d4 commit 6f090e5

File tree

4 files changed

+148
-3
lines changed

4 files changed

+148
-3
lines changed

src/ast/mod.rs

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3214,7 +3214,12 @@ impl fmt::Display for Statement {
32143214
Some(HiveRowFormat::SERDE { class }) => {
32153215
write!(f, " ROW FORMAT SERDE '{class}'")?
32163216
}
3217-
Some(HiveRowFormat::DELIMITED) => write!(f, " ROW FORMAT DELIMITED")?,
3217+
Some(HiveRowFormat::DELIMITED { delimiters }) => {
3218+
write!(f, " ROW FORMAT DELIMITED")?;
3219+
if !delimiters.is_empty() {
3220+
write!(f, " {}", display_separated(delimiters, " "))?;
3221+
}
3222+
}
32183223
None => (),
32193224
}
32203225
match storage {
@@ -4872,7 +4877,48 @@ pub enum HiveDistributionStyle {
48724877
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
48734878
pub enum HiveRowFormat {
48744879
SERDE { class: String },
4875-
DELIMITED,
4880+
DELIMITED { delimiters: Vec<HiveRowDelimiter> },
4881+
}
4882+
4883+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4884+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4885+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4886+
pub struct HiveRowDelimiter {
4887+
pub delimiter: HiveDelimiter,
4888+
pub char: Ident,
4889+
}
4890+
4891+
impl fmt::Display for HiveRowDelimiter {
4892+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4893+
write!(f, "{} ", self.delimiter)?;
4894+
write!(f, "{}", self.char)
4895+
}
4896+
}
4897+
4898+
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4899+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4900+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4901+
pub enum HiveDelimiter {
4902+
FieldsTerminatedBy,
4903+
FieldsEscapedBy,
4904+
CollectionItemsTerminatedBy,
4905+
MapKeysTerminatedBy,
4906+
LinesTerminatedBy,
4907+
NullDefinedAs,
4908+
}
4909+
4910+
impl fmt::Display for HiveDelimiter {
4911+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4912+
use HiveDelimiter::*;
4913+
f.write_str(match self {
4914+
FieldsTerminatedBy => "FIELDS TERMINATED BY",
4915+
FieldsEscapedBy => "ESCAPED BY",
4916+
CollectionItemsTerminatedBy => "COLLECTION ITEMS TERMINATED BY",
4917+
MapKeysTerminatedBy => "MAP KEYS TERMINATED BY",
4918+
LinesTerminatedBy => "LINES TERMINATED BY",
4919+
NullDefinedAs => "NULL DEFINED AS",
4920+
})
4921+
}
48764922
}
48774923

48784924
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]

src/keywords.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ define_keywords!(
153153
COLLATE,
154154
COLLATION,
155155
COLLECT,
156+
COLLECTION,
156157
COLUMN,
157158
COLUMNS,
158159
COMMENT,
@@ -212,6 +213,7 @@ define_keywords!(
212213
DEFAULT,
213214
DEFERRABLE,
214215
DEFERRED,
216+
DEFINED,
215217
DELAYED,
216218
DELETE,
217219
DELIMITED,
@@ -258,6 +260,7 @@ define_keywords!(
258260
EQUALS,
259261
ERROR,
260262
ESCAPE,
263+
ESCAPED,
261264
EVENT,
262265
EVERY,
263266
EXCEPT,
@@ -368,6 +371,7 @@ define_keywords!(
368371
ISOLATION,
369372
ISOWEEK,
370373
ISOYEAR,
374+
ITEMS,
371375
JAR,
372376
JOIN,
373377
JSON,
@@ -376,6 +380,7 @@ define_keywords!(
376380
JSON_TABLE,
377381
JULIAN,
378382
KEY,
383+
KEYS,
379384
KILL,
380385
LAG,
381386
LANGUAGE,
@@ -390,6 +395,7 @@ define_keywords!(
390395
LIKE,
391396
LIKE_REGEX,
392397
LIMIT,
398+
LINES,
393399
LISTAGG,
394400
LN,
395401
LOAD,
@@ -405,6 +411,7 @@ define_keywords!(
405411
LOW_PRIORITY,
406412
MACRO,
407413
MANAGEDLOCATION,
414+
MAP,
408415
MATCH,
409416
MATCHED,
410417
MATERIALIZED,
@@ -653,6 +660,7 @@ define_keywords!(
653660
TBLPROPERTIES,
654661
TEMP,
655662
TEMPORARY,
663+
TERMINATED,
656664
TEXT,
657665
TEXTFILE,
658666
THEN,

src/parser/mod.rs

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4405,7 +4405,92 @@ impl<'a> Parser<'a> {
44054405
let class = self.parse_literal_string()?;
44064406
Ok(HiveRowFormat::SERDE { class })
44074407
}
4408-
_ => Ok(HiveRowFormat::DELIMITED),
4408+
_ => {
4409+
let mut row_delimiters = vec![];
4410+
4411+
loop {
4412+
match self.parse_one_of_keywords(&[
4413+
Keyword::FIELDS,
4414+
Keyword::COLLECTION,
4415+
Keyword::MAP,
4416+
Keyword::LINES,
4417+
Keyword::NULL,
4418+
]) {
4419+
Some(Keyword::FIELDS) => {
4420+
if self.parse_keywords(&[Keyword::TERMINATED, Keyword::BY]) {
4421+
row_delimiters.push(HiveRowDelimiter {
4422+
delimiter: HiveDelimiter::FieldsTerminatedBy,
4423+
char: self.parse_identifier(false)?,
4424+
});
4425+
4426+
if self.parse_keywords(&[Keyword::ESCAPED, Keyword::BY]) {
4427+
row_delimiters.push(HiveRowDelimiter {
4428+
delimiter: HiveDelimiter::FieldsEscapedBy,
4429+
char: self.parse_identifier(false)?,
4430+
});
4431+
}
4432+
} else {
4433+
break;
4434+
}
4435+
}
4436+
Some(Keyword::COLLECTION) => {
4437+
if self.parse_keywords(&[
4438+
Keyword::ITEMS,
4439+
Keyword::TERMINATED,
4440+
Keyword::BY,
4441+
]) {
4442+
row_delimiters.push(HiveRowDelimiter {
4443+
delimiter: HiveDelimiter::CollectionItemsTerminatedBy,
4444+
char: self.parse_identifier(false)?,
4445+
});
4446+
} else {
4447+
break;
4448+
}
4449+
}
4450+
Some(Keyword::MAP) => {
4451+
if self.parse_keywords(&[
4452+
Keyword::KEYS,
4453+
Keyword::TERMINATED,
4454+
Keyword::BY,
4455+
]) {
4456+
row_delimiters.push(HiveRowDelimiter {
4457+
delimiter: HiveDelimiter::MapKeysTerminatedBy,
4458+
char: self.parse_identifier(false)?,
4459+
});
4460+
} else {
4461+
break;
4462+
}
4463+
}
4464+
Some(Keyword::LINES) => {
4465+
if self.parse_keywords(&[Keyword::TERMINATED, Keyword::BY]) {
4466+
row_delimiters.push(HiveRowDelimiter {
4467+
delimiter: HiveDelimiter::LinesTerminatedBy,
4468+
char: self.parse_identifier(false)?,
4469+
});
4470+
} else {
4471+
break;
4472+
}
4473+
}
4474+
Some(Keyword::NULL) => {
4475+
if self.parse_keywords(&[Keyword::DEFINED, Keyword::AS]) {
4476+
row_delimiters.push(HiveRowDelimiter {
4477+
delimiter: HiveDelimiter::NullDefinedAs,
4478+
char: self.parse_identifier(false)?,
4479+
});
4480+
} else {
4481+
break;
4482+
}
4483+
}
4484+
_ => {
4485+
break;
4486+
}
4487+
}
4488+
}
4489+
4490+
Ok(HiveRowFormat::DELIMITED {
4491+
delimiters: row_delimiters,
4492+
})
4493+
}
44094494
}
44104495
}
44114496

tests/sqlparser_hive.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,12 @@ fn create_temp_table() {
193193
hive().one_statement_parses_to(query2, query);
194194
}
195195

196+
#[test]
197+
fn create_delimited_table() {
198+
let query = "CREATE TABLE tab (cola STRING, colb BIGINT) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' ESCAPED BY '\"' MAP KEYS TERMINATED BY '\"'";
199+
hive().verified_stmt(query);
200+
}
201+
196202
#[test]
197203
fn create_local_directory() {
198204
let query =

0 commit comments

Comments
 (0)