Add support for Hive's LOAD DATA expr (#1520)

Co-authored-by: Ifeanyi Ubah <ify1992@yahoo.com>
This commit is contained in:
wugeer 2024-11-15 22:53:31 +08:00 committed by GitHub
parent 62eaee62dc
commit 724a1d1aba
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 323 additions and 11 deletions

View file

@ -543,10 +543,7 @@ impl<'a> Parser<'a> {
Keyword::INSTALL if dialect_of!(self is DuckDbDialect | GenericDialect) => {
self.parse_install()
}
// `LOAD` is duckdb specific https://duckdb.org/docs/extensions/overview
Keyword::LOAD if dialect_of!(self is DuckDbDialect | GenericDialect) => {
self.parse_load()
}
Keyword::LOAD => self.parse_load(),
// `OPTIMIZE` is clickhouse specific https://clickhouse.tech/docs/en/sql-reference/statements/optimize/
Keyword::OPTIMIZE if dialect_of!(self is ClickHouseDialect | GenericDialect) => {
self.parse_optimize_table()
@ -11222,6 +11219,22 @@ impl<'a> Parser<'a> {
}
}
pub fn parse_load_data_table_format(
&mut self,
) -> Result<Option<HiveLoadDataFormat>, ParserError> {
if self.parse_keyword(Keyword::INPUTFORMAT) {
let input_format = self.parse_expr()?;
self.expect_keyword(Keyword::SERDE)?;
let serde = self.parse_expr()?;
Ok(Some(HiveLoadDataFormat {
input_format,
serde,
}))
} else {
Ok(None)
}
}
/// Parse an UPDATE statement, returning a `Box`ed SetExpr
///
/// This is used to reduce the size of the stack frames in debug builds
@ -12224,10 +12237,35 @@ impl<'a> Parser<'a> {
Ok(Statement::Install { extension_name })
}
/// `LOAD [extension_name]`
/// Parse a SQL LOAD statement
pub fn parse_load(&mut self) -> Result<Statement, ParserError> {
let extension_name = self.parse_identifier(false)?;
Ok(Statement::Load { extension_name })
if self.dialect.supports_load_extension() {
let extension_name = self.parse_identifier(false)?;
Ok(Statement::Load { extension_name })
} else if self.parse_keyword(Keyword::DATA) && self.dialect.supports_load_data() {
let local = self.parse_one_of_keywords(&[Keyword::LOCAL]).is_some();
self.expect_keyword(Keyword::INPATH)?;
let inpath = self.parse_literal_string()?;
let overwrite = self.parse_one_of_keywords(&[Keyword::OVERWRITE]).is_some();
self.expect_keyword(Keyword::INTO)?;
self.expect_keyword(Keyword::TABLE)?;
let table_name = self.parse_object_name(false)?;
let partitioned = self.parse_insert_partition()?;
let table_format = self.parse_load_data_table_format()?;
Ok(Statement::LoadData {
local,
inpath,
overwrite,
table_name,
partitioned,
table_format,
})
} else {
self.expected(
"`DATA` or an extension name after `LOAD`",
self.peek_token(),
)
}
}
/// ```sql