Skip to content

Commit 991dbab

Browse files
jonathanlehtoalamb
andauthored
Support ALTER TABLE ... SET LOCATION (apache#1154)
Co-authored-by: Andrew Lamb <andrew@nerdnetworks.org>
1 parent 6f090e5 commit 991dbab

5 files changed

Lines changed: 59 additions & 7 deletions

File tree

src/ast/mod.rs

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2001,6 +2001,7 @@ pub enum Statement {
20012001
if_exists: bool,
20022002
only: bool,
20032003
operations: Vec<AlterTableOperation>,
2004+
location: Option<HiveSetLocation>,
20042005
},
20052006
/// ```sql
20062007
/// ALTER INDEX
@@ -3249,12 +3250,10 @@ impl fmt::Display for Statement {
32493250
}
32503251
}
32513252
if *external {
3252-
write!(
3253-
f,
3254-
" STORED AS {} LOCATION '{}'",
3255-
file_format.as_ref().unwrap(),
3256-
location.as_ref().unwrap()
3257-
)?;
3253+
if let Some(file_format) = &file_format {
3254+
write!(f, " STORED AS {file_format}")?;
3255+
}
3256+
write!(f, " LOCATION '{}'", location.as_ref().unwrap())?;
32583257
}
32593258
if !table_properties.is_empty() {
32603259
write!(
@@ -3504,6 +3503,7 @@ impl fmt::Display for Statement {
35043503
if_exists,
35053504
only,
35063505
operations,
3506+
location,
35073507
} => {
35083508
write!(f, "ALTER TABLE ")?;
35093509
if *if_exists {
@@ -3516,7 +3516,11 @@ impl fmt::Display for Statement {
35163516
f,
35173517
"{name} {operations}",
35183518
operations = display_comma_separated(operations)
3519-
)
3519+
)?;
3520+
if let Some(loc) = location {
3521+
write!(f, " {loc}")?
3522+
}
3523+
Ok(())
35203524
}
35213525
Statement::AlterIndex { name, operation } => {
35223526
write!(f, "ALTER INDEX {name} {operation}")
@@ -5840,6 +5844,23 @@ impl fmt::Display for LockTableType {
58405844
}
58415845
}
58425846

5847+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5848+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5849+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5850+
pub struct HiveSetLocation {
5851+
pub has_set: bool,
5852+
pub location: Ident,
5853+
}
5854+
5855+
impl fmt::Display for HiveSetLocation {
5856+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5857+
if self.has_set {
5858+
write!(f, "SET ")?;
5859+
}
5860+
write!(f, "LOCATION {}", self.location)
5861+
}
5862+
}
5863+
58435864
#[cfg(test)]
58445865
mod tests {
58455866
use super::*;

src/parser/mod.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5529,11 +5529,26 @@ impl<'a> Parser<'a> {
55295529
let only = self.parse_keyword(Keyword::ONLY); // [ ONLY ]
55305530
let table_name = self.parse_object_name(false)?;
55315531
let operations = self.parse_comma_separated(Parser::parse_alter_table_operation)?;
5532+
5533+
let mut location = None;
5534+
if self.parse_keyword(Keyword::LOCATION) {
5535+
location = Some(HiveSetLocation {
5536+
has_set: false,
5537+
location: self.parse_identifier(false)?,
5538+
});
5539+
} else if self.parse_keywords(&[Keyword::SET, Keyword::LOCATION]) {
5540+
location = Some(HiveSetLocation {
5541+
has_set: true,
5542+
location: self.parse_identifier(false)?,
5543+
});
5544+
}
5545+
55325546
Ok(Statement::AlterTable {
55335547
name: table_name,
55345548
if_exists,
55355549
only,
55365550
operations,
5551+
location,
55375552
})
55385553
}
55395554
Keyword::INDEX => {

src/test_utils.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,7 @@ pub fn alter_table_op_with_name(stmt: Statement, expected_name: &str) -> AlterTa
256256
if_exists,
257257
only: is_only,
258258
operations,
259+
location: _,
259260
} => {
260261
assert_eq!(name.to_string(), expected_name);
261262
assert!(!if_exists);
@@ -265,6 +266,7 @@ pub fn alter_table_op_with_name(stmt: Statement, expected_name: &str) -> AlterTa
265266
_ => panic!("Expected ALTER TABLE statement"),
266267
}
267268
}
269+
268270
pub fn alter_table_op(stmt: Statement) -> AlterTableOperation {
269271
alter_table_op_with_name(stmt, "tab")
270272
}

tests/sqlparser_hive.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,19 @@ fn test_alter_partition() {
124124
hive().verified_stmt(alter);
125125
}
126126

127+
#[test]
128+
fn test_alter_with_location() {
129+
let alter =
130+
"ALTER TABLE db.table PARTITION (a = 2) RENAME TO PARTITION (a = 1) LOCATION 's3://...'";
131+
hive().verified_stmt(alter);
132+
}
133+
134+
#[test]
135+
fn test_alter_with_set_location() {
136+
let alter = "ALTER TABLE db.table PARTITION (a = 2) RENAME TO PARTITION (a = 1) SET LOCATION 's3://...'";
137+
hive().verified_stmt(alter);
138+
}
139+
127140
#[test]
128141
fn test_add_partition() {
129142
let add = "ALTER TABLE db.table ADD IF NOT EXISTS PARTITION (a = 'asdf', b = 2)";

tests/sqlparser_postgres.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,7 @@ fn parse_alter_table_add_columns() {
677677
if_exists,
678678
only,
679679
operations,
680+
location: _,
680681
} => {
681682
assert_eq!(name.to_string(), "tab");
682683
assert!(if_exists);

0 commit comments

Comments
 (0)