From db4c2233c05cdb25dce2c6de3da4285c89ed9192 Mon Sep 17 00:00:00 2001 From: ZacJW Date: Sun, 22 Jun 2025 12:23:25 +0100 Subject: [PATCH 1/3] Add support for LANGUAGE clause in CREATE PROCEDURE --- src/ast/mod.rs | 6 ++++++ src/parser/mod.rs | 8 ++++++++ 2 files changed, 14 insertions(+) diff --git a/src/ast/mod.rs b/src/ast/mod.rs index 369489f56..420367ae8 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -3914,6 +3914,7 @@ pub enum Statement { or_alter: bool, name: ObjectName, params: Option>, + language: Option, body: ConditionalStatements, }, /// ```sql @@ -4817,6 +4818,7 @@ impl fmt::Display for Statement { name, or_alter, params, + language, body, } => { write!( @@ -4832,6 +4834,10 @@ impl fmt::Display for Statement { } } + if let Some(language) = language { + write!(f, " LANGUAGE {language}")?; + } + write!(f, " AS {body}") } Statement::CreateMacro { diff --git a/src/parser/mod.rs b/src/parser/mod.rs index be32093f3..b826f7ff0 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -15767,6 +15767,13 @@ impl<'a> Parser<'a> { pub fn parse_create_procedure(&mut self, or_alter: bool) -> Result { let name = self.parse_object_name(false)?; let params = self.parse_optional_procedure_parameters()?; + + let language = if self.parse_keyword(Keyword::LANGUAGE) { + Some(self.parse_identifier()?) + } else { + None + }; + self.expect_keyword_is(Keyword::AS)?; let body = self.parse_conditional_statements(&[Keyword::END])?; @@ -15775,6 +15782,7 @@ impl<'a> Parser<'a> { name, or_alter, params, + language, body, }) } From f4967660782d51a17ab6af1827c4a621a76903c5 Mon Sep 17 00:00:00 2001 From: ZacJW Date: Sun, 22 Jun 2025 12:43:04 +0100 Subject: [PATCH 2/3] Fix MS SQL test --- tests/sqlparser_mssql.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/sqlparser_mssql.rs b/tests/sqlparser_mssql.rs index 2a3145028..3ca17cd07 100644 --- a/tests/sqlparser_mssql.rs +++ b/tests/sqlparser_mssql.rs @@ -171,7 +171,8 @@ fn parse_create_procedure() { value: "test".into(), quote_style: None, span: Span::empty(), - }]) + }]), + language: None, } ) } From b91485a4e03336bb23b65a15f1886f8e9f7730ee Mon Sep 17 00:00:00 2001 From: ZacJW Date: Sun, 22 Jun 2025 12:50:16 +0100 Subject: [PATCH 3/3] Add testcase for CREATE PROCEDURE with LANGUAGE clause --- tests/sqlparser_common.rs | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs index e4363ff6e..0a1df2bd4 100644 --- a/tests/sqlparser_common.rs +++ b/tests/sqlparser_common.rs @@ -15349,3 +15349,33 @@ fn check_enforced() { "CREATE TABLE t (a INT, b INT, c INT, CHECK (a > 0) NOT ENFORCED, CHECK (b > 0) ENFORCED, CHECK (c > 0))", ); } + +#[test] +fn parse_create_procedure_with_language() { + let sql = r#"CREATE PROCEDURE test_proc LANGUAGE sql AS BEGIN SELECT 1; END"#; + match verified_stmt(sql) { + Statement::CreateProcedure { + or_alter, + name, + params, + language, + .. + } => { + assert_eq!(or_alter, false); + assert_eq!(name.to_string(), "test_proc"); + assert_eq!(params, Some(vec![])); + assert_eq!( + language, + Some(Ident { + value: "sql".into(), + quote_style: None, + span: Span { + start: Location::empty(), + end: Location::empty() + } + }) + ); + } + _ => unreachable!(), + } +}