From 6ac1b4d36ebb573fe481cca674f6db8add68e674 Mon Sep 17 00:00:00 2001 From: universalmind303 Date: Wed, 7 Feb 2024 14:58:35 -0600 Subject: [PATCH 1/5] feat: add duckdb "INSTALL" and "LOAD" --- src/ast/mod.rs | 21 +++++++++++++++++++++ src/keywords.rs | 2 ++ src/parser/mod.rs | 23 +++++++++++++++++++++++ tests/sqlparser_duckdb.rs | 28 ++++++++++++++++++++++++++++ 4 files changed, 74 insertions(+) diff --git a/src/ast/mod.rs b/src/ast/mod.rs index a2c28c810..788e8342a 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -1520,6 +1520,20 @@ pub enum Statement { /// Only for mysql priority: Option, }, + /// ```sql + /// INSTALL + /// ``` + Install { + /// Only for DuckDB + extension_name: Ident, + }, + /// ```sql + /// LOAD + /// ``` + Load { + /// Only for DuckDB + extension_name: Ident, + }, // TODO: Support ROW FORMAT Directory { overwrite: bool, @@ -2610,6 +2624,13 @@ impl fmt::Display for Statement { Ok(()) } + Statement::Install { + extension_name: name, + } => write!(f, "INSTALL {name}"), + + Statement::Load { + extension_name: name, + } => write!(f, "LOAD {name}"), Statement::Call(function) => write!(f, "CALL {function}"), diff --git a/src/keywords.rs b/src/keywords.rs index f14b92b76..771e86705 100644 --- a/src/keywords.rs +++ b/src/keywords.rs @@ -351,6 +351,7 @@ define_keywords!( INPUTFORMAT, INSENSITIVE, INSERT, + INSTALL, INT, INT2, INT4, @@ -390,6 +391,7 @@ define_keywords!( LIMIT, LISTAGG, LN, + LOAD, LOCAL, LOCALTIME, LOCALTIMESTAMP, diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 36ac2fd28..b24db3aac 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -460,6 +460,7 @@ impl<'a> Parser<'a> { } let next_token = self.next_token(); + println!("next_token: {:?}", next_token); match &next_token.token { Token::Word(w) => match w.keyword { Keyword::KILL => Ok(self.parse_kill()?), @@ -516,6 +517,15 @@ impl<'a> Parser<'a> { Keyword::MERGE => Ok(self.parse_merge()?), // `PRAGMA` is sqlite specific https://www.sqlite.org/pragma.html Keyword::PRAGMA => Ok(self.parse_pragma()?), + // `INSTALL` is duckdb specific https://duckdb.org/docs/extensions/overview + Keyword::INSTALL if dialect_of!(self is DuckDbDialect | GenericDialect) => { + Ok(self.parse_install()?) + } + // `LOAD` is duckdb specific https://duckdb.org/docs/extensions/overview + Keyword::LOAD if dialect_of!(self is DuckDbDialect | GenericDialect) => { + Ok(self.parse_load()?) + } + _ => self.expected("an SQL statement", next_token), }, Token::LParen => { @@ -8757,6 +8767,19 @@ impl<'a> Parser<'a> { }) } } + // INSTALL [extension_name] + pub fn parse_install(&mut self) -> Result { + let extension_name = self.parse_identifier(false)?; + + Ok(Statement::Install { extension_name }) + } + + // LOAD [extension_name] + + pub fn parse_load(&mut self) -> Result { + let extension_name = self.parse_identifier(false)?; + Ok(Statement::Load { extension_name }) + } /// ```sql /// CREATE [ { TEMPORARY | TEMP } ] SEQUENCE [ IF NOT EXISTS ] diff --git a/tests/sqlparser_duckdb.rs b/tests/sqlparser_duckdb.rs index db11d1e77..97bdd8e1c 100644 --- a/tests/sqlparser_duckdb.rs +++ b/tests/sqlparser_duckdb.rs @@ -216,3 +216,31 @@ fn test_select_union_by_name() { assert_eq!(ast.body, expected); } } + +#[test] +fn test_duckdb_install() { + let stmt = duckdb().verified_stmt("INSTALL tpch"); + assert_eq!( + stmt, + Statement::Install { + extension_name: Ident { + value: "tpch".to_string(), + quote_style: None + } + } + ); +} + +#[test] +fn test_duckdb_load_extension() { + let stmt = duckdb().verified_stmt("LOAD my_extension"); + assert_eq!( + Statement::Load { + extension_name: Ident { + value: "my_extension".to_string(), + quote_style: None + } + }, + stmt + ); +} From c864198924af01e0dca70f6e64ee7a7e71f5b336 Mon Sep 17 00:00:00 2001 From: universalmind303 Date: Wed, 7 Feb 2024 15:00:07 -0600 Subject: [PATCH 2/5] fix spacing --- src/parser/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/parser/mod.rs b/src/parser/mod.rs index b24db3aac..55b59c660 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -8767,15 +8767,15 @@ impl<'a> Parser<'a> { }) } } - // INSTALL [extension_name] + + /// INSTALL [extension_name] pub fn parse_install(&mut self) -> Result { let extension_name = self.parse_identifier(false)?; Ok(Statement::Install { extension_name }) } - // LOAD [extension_name] - + /// LOAD [extension_name] pub fn parse_load(&mut self) -> Result { let extension_name = self.parse_identifier(false)?; Ok(Statement::Load { extension_name }) From 9662e665569ee436dd240edaef48c1611ecddccb Mon Sep 17 00:00:00 2001 From: Andrew Lamb Date: Thu, 8 Feb 2024 20:21:03 -0500 Subject: [PATCH 3/5] fmt --- src/parser/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 3d44c2c90..bff146fe6 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -8785,7 +8785,7 @@ impl<'a> Parser<'a> { }) } } - + /// INSTALL [extension_name] pub fn parse_install(&mut self) -> Result { let extension_name = self.parse_identifier(false)?; From 150c3ad966a1508b26301e8c5a061a568357879b Mon Sep 17 00:00:00 2001 From: Andrew Lamb Date: Thu, 8 Feb 2024 20:21:50 -0500 Subject: [PATCH 4/5] fix doc build --- src/parser/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/parser/mod.rs b/src/parser/mod.rs index bff146fe6..2ccdbf75a 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -8786,14 +8786,14 @@ impl<'a> Parser<'a> { } } - /// INSTALL [extension_name] + /// `INSTALL [extension_name]` pub fn parse_install(&mut self) -> Result { let extension_name = self.parse_identifier(false)?; Ok(Statement::Install { extension_name }) } - /// LOAD [extension_name] + /// `LOAD [extension_name]` pub fn parse_load(&mut self) -> Result { let extension_name = self.parse_identifier(false)?; Ok(Statement::Load { extension_name }) From f4a7a18cdcc221f839df8b222a191245c6d85651 Mon Sep 17 00:00:00 2001 From: Andrew Lamb Date: Thu, 8 Feb 2024 20:24:22 -0500 Subject: [PATCH 5/5] remove stray println --- src/parser/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 2ccdbf75a..111684e46 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -460,7 +460,6 @@ impl<'a> Parser<'a> { } let next_token = self.next_token(); - println!("next_token: {:?}", next_token); match &next_token.token { Token::Word(w) => match w.keyword { Keyword::KILL => Ok(self.parse_kill()?),