Skip to content

Commit 99e6811

Browse files
aharpervcayman-sigma
authored andcommitted
Add support for procedure parameter default values (apache#2041)
1 parent a271503 commit 99e6811

File tree

4 files changed

+75
-5
lines changed

4 files changed

+75
-5
lines changed

src/ast/ddl.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1173,12 +1173,19 @@ pub struct ProcedureParam {
11731173
pub name: Ident,
11741174
pub data_type: DataType,
11751175
pub mode: Option<ArgMode>,
1176+
pub default: Option<Expr>,
11761177
}
11771178

11781179
impl fmt::Display for ProcedureParam {
11791180
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
11801181
if let Some(mode) = &self.mode {
1181-
write!(f, "{mode} {} {}", self.name, self.data_type)
1182+
if let Some(default) = &self.default {
1183+
write!(f, "{mode} {} {} = {}", self.name, self.data_type, default)
1184+
} else {
1185+
write!(f, "{mode} {} {}", self.name, self.data_type)
1186+
}
1187+
} else if let Some(default) = &self.default {
1188+
write!(f, "{} {} = {}", self.name, self.data_type, default)
11821189
} else {
11831190
write!(f, "{} {}", self.name, self.data_type)
11841191
}

src/parser/mod.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7935,10 +7935,17 @@ impl<'a> Parser<'a> {
79357935
};
79367936
let name = self.parse_identifier()?;
79377937
let data_type = self.parse_data_type()?;
7938+
let default = if self.consume_token(&Token::Eq) {
7939+
Some(self.parse_expr()?)
7940+
} else {
7941+
None
7942+
};
7943+
79387944
Ok(ProcedureParam {
79397945
name,
79407946
data_type,
79417947
mode,
7948+
default,
79427949
})
79437950
}
79447951

tests/sqlparser_common.rs

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16531,7 +16531,8 @@ fn parse_create_procedure_with_parameter_modes() {
1653116531
span: fake_span,
1653216532
},
1653316533
data_type: DataType::Integer(None),
16534-
mode: Some(ArgMode::In)
16534+
mode: Some(ArgMode::In),
16535+
default: None,
1653516536
},
1653616537
ProcedureParam {
1653716538
name: Ident {
@@ -16540,7 +16541,8 @@ fn parse_create_procedure_with_parameter_modes() {
1654016541
span: fake_span,
1654116542
},
1654216543
data_type: DataType::Text,
16543-
mode: Some(ArgMode::Out)
16544+
mode: Some(ArgMode::Out),
16545+
default: None,
1654416546
},
1654516547
ProcedureParam {
1654616548
name: Ident {
@@ -16549,7 +16551,8 @@ fn parse_create_procedure_with_parameter_modes() {
1654916551
span: fake_span,
1655016552
},
1655116553
data_type: DataType::Timestamp(None, TimezoneInfo::None),
16552-
mode: Some(ArgMode::InOut)
16554+
mode: Some(ArgMode::InOut),
16555+
default: None,
1655316556
},
1655416557
ProcedureParam {
1655516558
name: Ident {
@@ -16558,13 +16561,60 @@ fn parse_create_procedure_with_parameter_modes() {
1655816561
span: fake_span,
1655916562
},
1656016563
data_type: DataType::Bool,
16561-
mode: None
16564+
mode: None,
16565+
default: None,
1656216566
},
1656316567
])
1656416568
);
1656516569
}
1656616570
_ => unreachable!(),
1656716571
}
16572+
16573+
// parameters with default values
16574+
let sql = r#"CREATE PROCEDURE test_proc (IN a INTEGER = 1, OUT b TEXT = '2', INOUT c TIMESTAMP = NULL, d BOOL = 0) AS BEGIN SELECT 1; END"#;
16575+
match verified_stmt(sql) {
16576+
Statement::CreateProcedure {
16577+
or_alter,
16578+
name,
16579+
params,
16580+
..
16581+
} => {
16582+
assert_eq!(or_alter, false);
16583+
assert_eq!(name.to_string(), "test_proc");
16584+
assert_eq!(
16585+
params,
16586+
Some(vec![
16587+
ProcedureParam {
16588+
name: Ident::new("a"),
16589+
data_type: DataType::Integer(None),
16590+
mode: Some(ArgMode::In),
16591+
default: Some(Expr::Value((number("1")).with_empty_span())),
16592+
},
16593+
ProcedureParam {
16594+
name: Ident::new("b"),
16595+
data_type: DataType::Text,
16596+
mode: Some(ArgMode::Out),
16597+
default: Some(Expr::Value(
16598+
Value::SingleQuotedString("2".into()).with_empty_span()
16599+
)),
16600+
},
16601+
ProcedureParam {
16602+
name: Ident::new("c"),
16603+
data_type: DataType::Timestamp(None, TimezoneInfo::None),
16604+
mode: Some(ArgMode::InOut),
16605+
default: Some(Expr::Value(Value::Null.with_empty_span())),
16606+
},
16607+
ProcedureParam {
16608+
name: Ident::new("d"),
16609+
data_type: DataType::Bool,
16610+
mode: None,
16611+
default: Some(Expr::Value((number("0")).with_empty_span())),
16612+
}
16613+
]),
16614+
);
16615+
}
16616+
_ => unreachable!(),
16617+
}
1656816618
}
1656916619

1657016620
#[test]

tests/sqlparser_mssql.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ fn parse_create_procedure() {
156156
},
157157
data_type: DataType::Int(None),
158158
mode: None,
159+
default: None,
159160
},
160161
ProcedureParam {
161162
name: Ident {
@@ -168,6 +169,7 @@ fn parse_create_procedure() {
168169
unit: None
169170
})),
170171
mode: None,
172+
default: None,
171173
}
172174
]),
173175
name: ObjectName::from(vec![Ident {
@@ -196,6 +198,10 @@ fn parse_mssql_create_procedure() {
196198
let _ = ms().verified_stmt("CREATE PROCEDURE [foo] AS BEGIN SELECT [foo], CASE WHEN [foo] IS NULL THEN 'empty' ELSE 'notempty' END AS [foo]; END");
197199
// Multiple statements
198200
let _ = ms().verified_stmt("CREATE PROCEDURE [foo] AS BEGIN UPDATE bar SET col = 'test'; SELECT [foo] FROM BAR WHERE [FOO] > 10; END");
201+
202+
// parameters with default values
203+
let sql = r#"CREATE PROCEDURE foo (IN @a INTEGER = 1, OUT @b TEXT = '2', INOUT @c DATETIME = NULL, @d BOOL = 0) AS BEGIN SELECT 1; END"#;
204+
let _ = ms().verified_stmt(sql);
199205
}
200206

201207
#[test]

0 commit comments

Comments
 (0)