Skip to content

Commit d05b63c

Browse files
committed
Add support for procedure parameter default values
1 parent 3c61db5 commit d05b63c

File tree

4 files changed

+97
-5
lines changed

4 files changed

+97
-5
lines changed

src/ast/ddl.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1458,12 +1458,19 @@ pub struct ProcedureParam {
14581458
pub name: Ident,
14591459
pub data_type: DataType,
14601460
pub mode: Option<ArgMode>,
1461+
pub default: Option<Expr>,
14611462
}
14621463

14631464
impl fmt::Display for ProcedureParam {
14641465
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
14651466
if let Some(mode) = &self.mode {
1466-
write!(f, "{mode} {} {}", self.name, self.data_type)
1467+
if let Some(default) = &self.default {
1468+
write!(f, "{mode} {} {} = {}", self.name, self.data_type, default)
1469+
} else {
1470+
write!(f, "{mode} {} {}", self.name, self.data_type)
1471+
}
1472+
} else if let Some(default) = &self.default {
1473+
write!(f, "{} {} = {}", self.name, self.data_type, default)
14671474
} else {
14681475
write!(f, "{} {}", self.name, self.data_type)
14691476
}

src/parser/mod.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7897,10 +7897,17 @@ impl<'a> Parser<'a> {
78977897
};
78987898
let name = self.parse_identifier()?;
78997899
let data_type = self.parse_data_type()?;
7900+
let default = if self.consume_token(&Token::Eq) {
7901+
Some(self.parse_expr()?)
7902+
} else {
7903+
None
7904+
};
7905+
79007906
Ok(ProcedureParam {
79017907
name,
79027908
data_type,
79037909
mode,
7910+
default,
79047911
})
79057912
}
79067913

tests/sqlparser_common.rs

Lines changed: 74 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16497,7 +16497,8 @@ fn parse_create_procedure_with_parameter_modes() {
1649716497
span: fake_span,
1649816498
},
1649916499
data_type: DataType::Integer(None),
16500-
mode: Some(ArgMode::In)
16500+
mode: Some(ArgMode::In),
16501+
default: None,
1650116502
},
1650216503
ProcedureParam {
1650316504
name: Ident {
@@ -16506,7 +16507,8 @@ fn parse_create_procedure_with_parameter_modes() {
1650616507
span: fake_span,
1650716508
},
1650816509
data_type: DataType::Text,
16509-
mode: Some(ArgMode::Out)
16510+
mode: Some(ArgMode::Out),
16511+
default: None,
1651016512
},
1651116513
ProcedureParam {
1651216514
name: Ident {
@@ -16515,7 +16517,8 @@ fn parse_create_procedure_with_parameter_modes() {
1651516517
span: fake_span,
1651616518
},
1651716519
data_type: DataType::Timestamp(None, TimezoneInfo::None),
16518-
mode: Some(ArgMode::InOut)
16520+
mode: Some(ArgMode::InOut),
16521+
default: None,
1651916522
},
1652016523
ProcedureParam {
1652116524
name: Ident {
@@ -16524,7 +16527,8 @@ fn parse_create_procedure_with_parameter_modes() {
1652416527
span: fake_span,
1652516528
},
1652616529
data_type: DataType::Bool,
16527-
mode: None
16530+
mode: None,
16531+
default: None,
1652816532
},
1652916533
])
1653016534
);
@@ -16533,6 +16537,72 @@ fn parse_create_procedure_with_parameter_modes() {
1653316537
}
1653416538
}
1653516539

16540+
#[test]
16541+
fn create_procedure_with_parameter_default_value() {
16542+
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"#;
16543+
match verified_stmt(sql) {
16544+
Statement::CreateProcedure {
16545+
or_alter,
16546+
name,
16547+
params,
16548+
..
16549+
} => {
16550+
assert_eq!(or_alter, false);
16551+
assert_eq!(name.to_string(), "test_proc");
16552+
let fake_span = Span {
16553+
start: Location { line: 0, column: 0 },
16554+
end: Location { line: 0, column: 0 },
16555+
};
16556+
assert_eq!(
16557+
params,
16558+
Some(vec![
16559+
ProcedureParam {
16560+
name: Ident {
16561+
value: "a".into(),
16562+
quote_style: None,
16563+
span: fake_span,
16564+
},
16565+
data_type: DataType::Integer(None),
16566+
mode: Some(ArgMode::In),
16567+
default: Some(Expr::Value((number("1")).with_empty_span())),
16568+
},
16569+
ProcedureParam {
16570+
name: Ident {
16571+
value: "b".into(),
16572+
quote_style: None,
16573+
span: fake_span,
16574+
},
16575+
data_type: DataType::Text,
16576+
mode: Some(ArgMode::Out),
16577+
default: Some(Expr::Value(Value::SingleQuotedString("2".into()).with_empty_span())),
16578+
},
16579+
ProcedureParam {
16580+
name: Ident {
16581+
value: "c".into(),
16582+
quote_style: None,
16583+
span: fake_span,
16584+
},
16585+
data_type: DataType::Timestamp(None, TimezoneInfo::None),
16586+
mode: Some(ArgMode::InOut),
16587+
default: Some(Expr::Value(Value::Null.with_empty_span())),
16588+
},
16589+
ProcedureParam {
16590+
name: Ident {
16591+
value: "d".into(),
16592+
quote_style: None,
16593+
span: fake_span,
16594+
},
16595+
data_type: DataType::Bool,
16596+
mode: None,
16597+
default: Some(Expr::Value((number("0")).with_empty_span())),
16598+
}
16599+
]),
16600+
);
16601+
}
16602+
_ => unreachable!(),
16603+
}
16604+
}
16605+
1653616606
#[test]
1653716607
fn parse_not_null() {
1653816608
let _ = all_dialects().expr_parses_to("x NOT NULL", "x IS NOT NULL");

tests/sqlparser_mssql.rs

Lines changed: 8 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 {
@@ -198,6 +200,12 @@ fn parse_mssql_create_procedure() {
198200
let _ = ms().verified_stmt("CREATE PROCEDURE [foo] AS BEGIN UPDATE bar SET col = 'test'; SELECT [foo] FROM BAR WHERE [FOO] > 10; END");
199201
}
200202

203+
#[test]
204+
fn parse_mssql_create_procedure_with_parameter_default_value() {
205+
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"#;
206+
let _ = ms().verified_stmt(sql);
207+
}
208+
201209
#[test]
202210
fn parse_create_function() {
203211
let return_expression_function = "CREATE FUNCTION some_scalar_udf(@foo INT, @bar VARCHAR(256)) RETURNS INT AS BEGIN RETURN 1; END";

0 commit comments

Comments
 (0)