Skip to content

Commit f487cbe

Browse files
Add GLOBAL context/modifier to SET statements (#1767)
1 parent e3e8829 commit f487cbe

File tree

7 files changed

+72
-39
lines changed

7 files changed

+72
-39
lines changed

src/ast/mod.rs

+12-7
Original file line numberDiff line numberDiff line change
@@ -2629,7 +2629,7 @@ pub enum Set {
26292629
/// SQL Standard-style
26302630
/// SET a = 1;
26312631
SingleAssignment {
2632-
local: bool,
2632+
scope: ContextModifier,
26332633
hivevar: bool,
26342634
variable: ObjectName,
26352635
values: Vec<Expr>,
@@ -2711,7 +2711,7 @@ impl Display for Set {
27112711
role_name,
27122712
} => {
27132713
let role_name = role_name.clone().unwrap_or_else(|| Ident::new("NONE"));
2714-
write!(f, "SET{context_modifier} ROLE {role_name}")
2714+
write!(f, "SET {context_modifier}ROLE {role_name}")
27152715
}
27162716
Self::SetSessionParam(kind) => write!(f, "SET {kind}"),
27172717
Self::SetTransaction {
@@ -2758,15 +2758,15 @@ impl Display for Set {
27582758
Ok(())
27592759
}
27602760
Set::SingleAssignment {
2761-
local,
2761+
scope,
27622762
hivevar,
27632763
variable,
27642764
values,
27652765
} => {
27662766
write!(
27672767
f,
27682768
"SET {}{}{} = {}",
2769-
if *local { "LOCAL " } else { "" },
2769+
scope,
27702770
if *hivevar { "HIVEVAR:" } else { "" },
27712771
variable,
27722772
display_comma_separated(values)
@@ -7955,7 +7955,7 @@ impl fmt::Display for FlushLocation {
79557955
}
79567956
}
79577957

7958-
/// Optional context modifier for statements that can be or `LOCAL`, or `SESSION`.
7958+
/// Optional context modifier for statements that can be or `LOCAL`, `GLOBAL`, or `SESSION`.
79597959
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
79607960
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
79617961
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
@@ -7966,6 +7966,8 @@ pub enum ContextModifier {
79667966
Local,
79677967
/// `SESSION` identifier
79687968
Session,
7969+
/// `GLOBAL` identifier
7970+
Global,
79697971
}
79707972

79717973
impl fmt::Display for ContextModifier {
@@ -7975,10 +7977,13 @@ impl fmt::Display for ContextModifier {
79757977
write!(f, "")
79767978
}
79777979
Self::Local => {
7978-
write!(f, " LOCAL")
7980+
write!(f, "LOCAL ")
79797981
}
79807982
Self::Session => {
7981-
write!(f, " SESSION")
7983+
write!(f, "SESSION ")
7984+
}
7985+
Self::Global => {
7986+
write!(f, "GLOBAL ")
79827987
}
79837988
}
79847989
}

src/parser/mod.rs

+19-10
Original file line numberDiff line numberDiff line change
@@ -1819,6 +1819,15 @@ impl<'a> Parser<'a> {
18191819
})
18201820
}
18211821

1822+
fn keyword_to_modifier(k: Option<Keyword>) -> ContextModifier {
1823+
match k {
1824+
Some(Keyword::LOCAL) => ContextModifier::Local,
1825+
Some(Keyword::GLOBAL) => ContextModifier::Global,
1826+
Some(Keyword::SESSION) => ContextModifier::Session,
1827+
_ => ContextModifier::None,
1828+
}
1829+
}
1830+
18221831
/// Check if the root is an identifier and all fields are identifiers.
18231832
fn is_all_ident(root: &Expr, fields: &[AccessExpr]) -> bool {
18241833
if !matches!(root, Expr::Identifier(_)) {
@@ -11138,11 +11147,7 @@ impl<'a> Parser<'a> {
1113811147
/// Parse a `SET ROLE` statement. Expects SET to be consumed already.
1113911148
fn parse_set_role(&mut self, modifier: Option<Keyword>) -> Result<Statement, ParserError> {
1114011149
self.expect_keyword_is(Keyword::ROLE)?;
11141-
let context_modifier = match modifier {
11142-
Some(Keyword::LOCAL) => ContextModifier::Local,
11143-
Some(Keyword::SESSION) => ContextModifier::Session,
11144-
_ => ContextModifier::None,
11145-
};
11150+
let context_modifier = Self::keyword_to_modifier(modifier);
1114611151

1114711152
let role_name = if self.parse_keyword(Keyword::NONE) {
1114811153
None
@@ -11214,8 +11219,12 @@ impl<'a> Parser<'a> {
1121411219
}
1121511220

1121611221
fn parse_set(&mut self) -> Result<Statement, ParserError> {
11217-
let modifier =
11218-
self.parse_one_of_keywords(&[Keyword::SESSION, Keyword::LOCAL, Keyword::HIVEVAR]);
11222+
let modifier = self.parse_one_of_keywords(&[
11223+
Keyword::SESSION,
11224+
Keyword::LOCAL,
11225+
Keyword::HIVEVAR,
11226+
Keyword::GLOBAL,
11227+
]);
1121911228

1122011229
if let Some(Keyword::HIVEVAR) = modifier {
1122111230
self.expect_token(&Token::Colon)?;
@@ -11231,7 +11240,7 @@ impl<'a> Parser<'a> {
1123111240
{
1123211241
if self.consume_token(&Token::Eq) || self.parse_keyword(Keyword::TO) {
1123311242
return Ok(Set::SingleAssignment {
11234-
local: modifier == Some(Keyword::LOCAL),
11243+
scope: Self::keyword_to_modifier(modifier),
1123511244
hivevar: modifier == Some(Keyword::HIVEVAR),
1123611245
variable: ObjectName::from(vec!["TIMEZONE".into()]),
1123711246
values: self.parse_set_values(false)?,
@@ -11321,7 +11330,7 @@ impl<'a> Parser<'a> {
1132111330
}?;
1132211331

1132311332
Ok(Set::SingleAssignment {
11324-
local: modifier == Some(Keyword::LOCAL),
11333+
scope: Self::keyword_to_modifier(modifier),
1132511334
hivevar: modifier == Some(Keyword::HIVEVAR),
1132611335
variable,
1132711336
values,
@@ -11349,7 +11358,7 @@ impl<'a> Parser<'a> {
1134911358
if self.consume_token(&Token::Eq) || self.parse_keyword(Keyword::TO) {
1135011359
let stmt = match variables {
1135111360
OneOrManyWithParens::One(var) => Set::SingleAssignment {
11352-
local: modifier == Some(Keyword::LOCAL),
11361+
scope: Self::keyword_to_modifier(modifier),
1135311362
hivevar: modifier == Some(Keyword::HIVEVAR),
1135411363
variable: var,
1135511364
values: self.parse_set_values(false)?,

tests/sqlparser_common.rs

+26-6
Original file line numberDiff line numberDiff line change
@@ -8627,12 +8627,12 @@ fn parse_set_transaction() {
86278627
fn parse_set_variable() {
86288628
match verified_stmt("SET SOMETHING = '1'") {
86298629
Statement::Set(Set::SingleAssignment {
8630-
local,
8630+
scope,
86318631
hivevar,
86328632
variable,
86338633
values,
86348634
}) => {
8635-
assert!(!local);
8635+
assert_eq!(scope, ContextModifier::None);
86368636
assert!(!hivevar);
86378637
assert_eq!(variable, ObjectName::from(vec!["SOMETHING".into()]));
86388638
assert_eq!(
@@ -8645,6 +8645,26 @@ fn parse_set_variable() {
86458645
_ => unreachable!(),
86468646
}
86478647

8648+
match verified_stmt("SET GLOBAL VARIABLE = 'Value'") {
8649+
Statement::Set(Set::SingleAssignment {
8650+
scope,
8651+
hivevar,
8652+
variable,
8653+
values,
8654+
}) => {
8655+
assert_eq!(scope, ContextModifier::Global);
8656+
assert!(!hivevar);
8657+
assert_eq!(variable, ObjectName::from(vec!["VARIABLE".into()]));
8658+
assert_eq!(
8659+
values,
8660+
vec![Expr::Value(
8661+
(Value::SingleQuotedString("Value".into())).with_empty_span()
8662+
)]
8663+
);
8664+
}
8665+
_ => unreachable!(),
8666+
}
8667+
86488668
let multi_variable_dialects = all_dialects_where(|d| d.supports_parenthesized_set_variables());
86498669
let sql = r#"SET (a, b, c) = (1, 2, 3)"#;
86508670
match multi_variable_dialects.verified_stmt(sql) {
@@ -8719,12 +8739,12 @@ fn parse_set_variable() {
87198739
fn parse_set_role_as_variable() {
87208740
match verified_stmt("SET role = 'foobar'") {
87218741
Statement::Set(Set::SingleAssignment {
8722-
local,
8742+
scope,
87238743
hivevar,
87248744
variable,
87258745
values,
87268746
}) => {
8727-
assert!(!local);
8747+
assert_eq!(scope, ContextModifier::None);
87288748
assert!(!hivevar);
87298749
assert_eq!(variable, ObjectName::from(vec!["role".into()]));
87308750
assert_eq!(
@@ -8766,12 +8786,12 @@ fn parse_double_colon_cast_at_timezone() {
87668786
fn parse_set_time_zone() {
87678787
match verified_stmt("SET TIMEZONE = 'UTC'") {
87688788
Statement::Set(Set::SingleAssignment {
8769-
local,
8789+
scope,
87708790
hivevar,
87718791
variable,
87728792
values,
87738793
}) => {
8774-
assert!(!local);
8794+
assert_eq!(scope, ContextModifier::None);
87758795
assert!(!hivevar);
87768796
assert_eq!(variable, ObjectName::from(vec!["TIMEZONE".into()]));
87778797
assert_eq!(

tests/sqlparser_hive.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,10 @@
2121
//! is also tested (on the inputs it can handle).
2222
2323
use sqlparser::ast::{
24-
ClusteredBy, CommentDef, CreateFunction, CreateFunctionBody, CreateFunctionUsing, CreateTable,
25-
Expr, Function, FunctionArgumentList, FunctionArguments, Ident, ObjectName, OrderByExpr,
26-
OrderByOptions, SelectItem, Set, Statement, TableFactor, UnaryOperator, Use, Value,
24+
ClusteredBy, CommentDef, ContextModifier, CreateFunction, CreateFunctionBody,
25+
CreateFunctionUsing, CreateTable, Expr, Function, FunctionArgumentList, FunctionArguments,
26+
Ident, ObjectName, OrderByExpr, OrderByOptions, SelectItem, Set, Statement, TableFactor,
27+
UnaryOperator, Use, Value,
2728
};
2829
use sqlparser::dialect::{GenericDialect, HiveDialect, MsSqlDialect};
2930
use sqlparser::parser::ParserError;
@@ -369,7 +370,7 @@ fn set_statement_with_minus() {
369370
assert_eq!(
370371
hive().verified_stmt("SET hive.tez.java.opts = -Xmx4g"),
371372
Statement::Set(Set::SingleAssignment {
372-
local: false,
373+
scope: ContextModifier::None,
373374
hivevar: false,
374375
variable: ObjectName::from(vec![
375376
Ident::new("hive"),

tests/sqlparser_mssql.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1251,7 +1251,7 @@ fn parse_mssql_declare() {
12511251
}]
12521252
},
12531253
Statement::Set(Set::SingleAssignment {
1254-
local: false,
1254+
scope: ContextModifier::None,
12551255
hivevar: false,
12561256
variable: ObjectName::from(vec![Ident::new("@bar")]),
12571257
values: vec![Expr::Value(

tests/sqlparser_mysql.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -618,7 +618,7 @@ fn parse_set_variables() {
618618
assert_eq!(
619619
mysql_and_generic().verified_stmt("SET LOCAL autocommit = 1"),
620620
Statement::Set(Set::SingleAssignment {
621-
local: true,
621+
scope: ContextModifier::Local,
622622
hivevar: false,
623623
variable: ObjectName::from(vec!["autocommit".into()]),
624624
values: vec![Expr::value(number("1"))],

tests/sqlparser_postgres.rs

+8-10
Original file line numberDiff line numberDiff line change
@@ -988,8 +988,7 @@ fn parse_create_schema_if_not_exists() {
988988
Statement::CreateSchema {
989989
if_not_exists: true,
990990
schema_name,
991-
options: _,
992-
default_collate_spec: _,
991+
..
993992
} => assert_eq!("schema_name", schema_name.to_string()),
994993
_ => unreachable!(),
995994
}
@@ -1433,7 +1432,7 @@ fn parse_set() {
14331432
assert_eq!(
14341433
stmt,
14351434
Statement::Set(Set::SingleAssignment {
1436-
local: false,
1435+
scope: ContextModifier::None,
14371436
hivevar: false,
14381437
variable: ObjectName::from(vec![Ident::new("a")]),
14391438
values: vec![Expr::Identifier(Ident {
@@ -1448,7 +1447,7 @@ fn parse_set() {
14481447
assert_eq!(
14491448
stmt,
14501449
Statement::Set(Set::SingleAssignment {
1451-
local: false,
1450+
scope: ContextModifier::None,
14521451
hivevar: false,
14531452
variable: ObjectName::from(vec![Ident::new("a")]),
14541453
values: vec![Expr::Value(
@@ -1461,7 +1460,7 @@ fn parse_set() {
14611460
assert_eq!(
14621461
stmt,
14631462
Statement::Set(Set::SingleAssignment {
1464-
local: false,
1463+
scope: ContextModifier::None,
14651464
hivevar: false,
14661465
variable: ObjectName::from(vec![Ident::new("a")]),
14671466
values: vec![Expr::value(number("0"))],
@@ -1472,7 +1471,7 @@ fn parse_set() {
14721471
assert_eq!(
14731472
stmt,
14741473
Statement::Set(Set::SingleAssignment {
1475-
local: false,
1474+
scope: ContextModifier::None,
14761475
hivevar: false,
14771476
variable: ObjectName::from(vec![Ident::new("a")]),
14781477
values: vec![Expr::Identifier(Ident::new("DEFAULT"))],
@@ -1483,7 +1482,7 @@ fn parse_set() {
14831482
assert_eq!(
14841483
stmt,
14851484
Statement::Set(Set::SingleAssignment {
1486-
local: true,
1485+
scope: ContextModifier::Local,
14871486
hivevar: false,
14881487
variable: ObjectName::from(vec![Ident::new("a")]),
14891488
values: vec![Expr::Identifier("b".into())],
@@ -1494,7 +1493,7 @@ fn parse_set() {
14941493
assert_eq!(
14951494
stmt,
14961495
Statement::Set(Set::SingleAssignment {
1497-
local: false,
1496+
scope: ContextModifier::None,
14981497
hivevar: false,
14991498
variable: ObjectName::from(vec![Ident::new("a"), Ident::new("b"), Ident::new("c")]),
15001499
values: vec![Expr::Identifier(Ident {
@@ -1512,7 +1511,7 @@ fn parse_set() {
15121511
assert_eq!(
15131512
stmt,
15141513
Statement::Set(Set::SingleAssignment {
1515-
local: false,
1514+
scope: ContextModifier::None,
15161515
hivevar: false,
15171516
variable: ObjectName::from(vec![
15181517
Ident::new("hive"),
@@ -1526,7 +1525,6 @@ fn parse_set() {
15261525
);
15271526

15281527
pg_and_generic().one_statement_parses_to("SET a TO b", "SET a = b");
1529-
pg_and_generic().one_statement_parses_to("SET SESSION a = b", "SET a = b");
15301528

15311529
assert_eq!(
15321530
pg_and_generic().parse_sql_statements("SET"),

0 commit comments

Comments
 (0)