Skip to content

Commit a5ac425

Browse files
feat: add duckdb "INSTALL" and "LOAD" (#1127)
Co-authored-by: Andrew Lamb <andrew@nerdnetworks.org>
1 parent d981b09 commit a5ac425

File tree

4 files changed

+73
-0
lines changed

4 files changed

+73
-0
lines changed

src/ast/mod.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1537,6 +1537,20 @@ pub enum Statement {
15371537
/// Only for mysql
15381538
priority: Option<MysqlInsertPriority>,
15391539
},
1540+
/// ```sql
1541+
/// INSTALL
1542+
/// ```
1543+
Install {
1544+
/// Only for DuckDB
1545+
extension_name: Ident,
1546+
},
1547+
/// ```sql
1548+
/// LOAD
1549+
/// ```
1550+
Load {
1551+
/// Only for DuckDB
1552+
extension_name: Ident,
1553+
},
15401554
// TODO: Support ROW FORMAT
15411555
Directory {
15421556
overwrite: bool,
@@ -2637,6 +2651,13 @@ impl fmt::Display for Statement {
26372651

26382652
Ok(())
26392653
}
2654+
Statement::Install {
2655+
extension_name: name,
2656+
} => write!(f, "INSTALL {name}"),
2657+
2658+
Statement::Load {
2659+
extension_name: name,
2660+
} => write!(f, "LOAD {name}"),
26402661

26412662
Statement::Call(function) => write!(f, "CALL {function}"),
26422663

src/keywords.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,7 @@ define_keywords!(
351351
INPUTFORMAT,
352352
INSENSITIVE,
353353
INSERT,
354+
INSTALL,
354355
INT,
355356
INT2,
356357
INT4,
@@ -390,6 +391,7 @@ define_keywords!(
390391
LIMIT,
391392
LISTAGG,
392393
LN,
394+
LOAD,
393395
LOCAL,
394396
LOCALTIME,
395397
LOCALTIMESTAMP,

src/parser/mod.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,15 @@ impl<'a> Parser<'a> {
516516
Keyword::MERGE => Ok(self.parse_merge()?),
517517
// `PRAGMA` is sqlite specific https://www.sqlite.org/pragma.html
518518
Keyword::PRAGMA => Ok(self.parse_pragma()?),
519+
// `INSTALL` is duckdb specific https://duckdb.org/docs/extensions/overview
520+
Keyword::INSTALL if dialect_of!(self is DuckDbDialect | GenericDialect) => {
521+
Ok(self.parse_install()?)
522+
}
523+
// `LOAD` is duckdb specific https://duckdb.org/docs/extensions/overview
524+
Keyword::LOAD if dialect_of!(self is DuckDbDialect | GenericDialect) => {
525+
Ok(self.parse_load()?)
526+
}
527+
519528
_ => self.expected("an SQL statement", next_token),
520529
},
521530
Token::LParen => {
@@ -8791,6 +8800,19 @@ impl<'a> Parser<'a> {
87918800
}
87928801
}
87938802

8803+
/// `INSTALL [extension_name]`
8804+
pub fn parse_install(&mut self) -> Result<Statement, ParserError> {
8805+
let extension_name = self.parse_identifier(false)?;
8806+
8807+
Ok(Statement::Install { extension_name })
8808+
}
8809+
8810+
/// `LOAD [extension_name]`
8811+
pub fn parse_load(&mut self) -> Result<Statement, ParserError> {
8812+
let extension_name = self.parse_identifier(false)?;
8813+
Ok(Statement::Load { extension_name })
8814+
}
8815+
87948816
/// ```sql
87958817
/// CREATE [ { TEMPORARY | TEMP } ] SEQUENCE [ IF NOT EXISTS ] <sequence_name>
87968818
/// ```

tests/sqlparser_duckdb.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,3 +216,31 @@ fn test_select_union_by_name() {
216216
assert_eq!(ast.body, expected);
217217
}
218218
}
219+
220+
#[test]
221+
fn test_duckdb_install() {
222+
let stmt = duckdb().verified_stmt("INSTALL tpch");
223+
assert_eq!(
224+
stmt,
225+
Statement::Install {
226+
extension_name: Ident {
227+
value: "tpch".to_string(),
228+
quote_style: None
229+
}
230+
}
231+
);
232+
}
233+
234+
#[test]
235+
fn test_duckdb_load_extension() {
236+
let stmt = duckdb().verified_stmt("LOAD my_extension");
237+
assert_eq!(
238+
Statement::Load {
239+
extension_name: Ident {
240+
value: "my_extension".to_string(),
241+
quote_style: None
242+
}
243+
},
244+
stmt
245+
);
246+
}

0 commit comments

Comments
 (0)