sqlparser/parser/
alter.rs

1// Licensed under the Apache License, Version 2.0 (the "License");
2// you may not use this file except in compliance with the License.
3// You may obtain a copy of the License at
4//
5// http://www.apache.org/licenses/LICENSE-2.0
6//
7// Unless required by applicable law or agreed to in writing, software
8// distributed under the License is distributed on an "AS IS" BASIS,
9// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10// See the License for the specific language governing permissions and
11// limitations under the License.
12
13//! SQL Parser for ALTER
14
15#[cfg(not(feature = "std"))]
16use alloc::vec;
17
18use super::{Parser, ParserError};
19use crate::{
20    ast::{AlterRoleOperation, Expr, Password, ResetConfig, RoleOption, SetConfigValue, Statement},
21    dialect::{MsSqlDialect, PostgreSqlDialect},
22    keywords::Keyword,
23    tokenizer::Token,
24};
25
26impl<'a> Parser<'a> {
27    pub fn parse_alter_role(&mut self) -> Result<Statement, ParserError> {
28        if dialect_of!(self is PostgreSqlDialect) {
29            return self.parse_pg_alter_role();
30        } else if dialect_of!(self is MsSqlDialect) {
31            return self.parse_mssql_alter_role();
32        }
33
34        Err(ParserError::ParserError(
35            "ALTER ROLE is only support for PostgreSqlDialect, MsSqlDialect".into(),
36        ))
37    }
38
39    fn parse_mssql_alter_role(&mut self) -> Result<Statement, ParserError> {
40        let role_name = self.parse_identifier()?;
41
42        let operation = if self.parse_keywords(&[Keyword::ADD, Keyword::MEMBER]) {
43            let member_name = self.parse_identifier()?;
44            AlterRoleOperation::AddMember { member_name }
45        } else if self.parse_keywords(&[Keyword::DROP, Keyword::MEMBER]) {
46            let member_name = self.parse_identifier()?;
47            AlterRoleOperation::DropMember { member_name }
48        } else if self.parse_keywords(&[Keyword::WITH, Keyword::NAME]) {
49            if self.consume_token(&Token::Eq) {
50                let role_name = self.parse_identifier()?;
51                AlterRoleOperation::RenameRole { role_name }
52            } else {
53                return self.expected("= after WITH NAME ", self.peek_token());
54            }
55        } else {
56            return self.expected("'ADD' or 'DROP' or 'WITH NAME'", self.peek_token());
57        };
58
59        Ok(Statement::AlterRole {
60            name: role_name,
61            operation,
62        })
63    }
64
65    fn parse_pg_alter_role(&mut self) -> Result<Statement, ParserError> {
66        let role_name = self.parse_identifier()?;
67
68        // [ IN DATABASE _`database_name`_ ]
69        let in_database = if self.parse_keywords(&[Keyword::IN, Keyword::DATABASE]) {
70            self.parse_object_name().ok()
71        } else {
72            None
73        };
74
75        let operation = if self.parse_keyword(Keyword::RENAME) {
76            if self.parse_keyword(Keyword::TO) {
77                let role_name = self.parse_identifier()?;
78                AlterRoleOperation::RenameRole { role_name }
79            } else {
80                return self.expected("TO after RENAME", self.peek_token());
81            }
82        // SET
83        } else if self.parse_keyword(Keyword::SET) {
84            let config_name = self.parse_object_name()?;
85            // FROM CURRENT
86            if self.parse_keywords(&[Keyword::FROM, Keyword::CURRENT]) {
87                AlterRoleOperation::Set {
88                    config_name,
89                    config_value: SetConfigValue::FromCurrent,
90                    in_database,
91                }
92            // { TO | = } { value | DEFAULT }
93            } else if self.consume_token(&Token::Eq) || self.parse_keyword(Keyword::TO) {
94                if self.parse_keyword(Keyword::DEFAULT) {
95                    AlterRoleOperation::Set {
96                        config_name,
97                        config_value: SetConfigValue::Default,
98                        in_database,
99                    }
100                } else if let Ok(expr) = self.parse_expr() {
101                    AlterRoleOperation::Set {
102                        config_name,
103                        config_value: SetConfigValue::Value(expr),
104                        in_database,
105                    }
106                } else {
107                    self.expected("config value", self.peek_token())?
108                }
109            } else {
110                self.expected("'TO' or '=' or 'FROM CURRENT'", self.peek_token())?
111            }
112        // RESET
113        } else if self.parse_keyword(Keyword::RESET) {
114            if self.parse_keyword(Keyword::ALL) {
115                AlterRoleOperation::Reset {
116                    config_name: ResetConfig::ALL,
117                    in_database,
118                }
119            } else {
120                let config_name = self.parse_object_name()?;
121                AlterRoleOperation::Reset {
122                    config_name: ResetConfig::ConfigName(config_name),
123                    in_database,
124                }
125            }
126        // option
127        } else {
128            // [ WITH ]
129            let _ = self.parse_keyword(Keyword::WITH);
130            // option
131            let mut options = vec![];
132            while let Some(opt) = self.maybe_parse(|parser| parser.parse_pg_role_option()) {
133                options.push(opt);
134            }
135            // check option
136            if options.is_empty() {
137                return self.expected("option", self.peek_token())?;
138            }
139
140            AlterRoleOperation::WithOptions { options }
141        };
142
143        Ok(Statement::AlterRole {
144            name: role_name,
145            operation,
146        })
147    }
148
149    fn parse_pg_role_option(&mut self) -> Result<RoleOption, ParserError> {
150        let option = match self.parse_one_of_keywords(&[
151            Keyword::BYPASSRLS,
152            Keyword::NOBYPASSRLS,
153            Keyword::CONNECTION,
154            Keyword::CREATEDB,
155            Keyword::NOCREATEDB,
156            Keyword::CREATEROLE,
157            Keyword::NOCREATEROLE,
158            Keyword::INHERIT,
159            Keyword::NOINHERIT,
160            Keyword::LOGIN,
161            Keyword::NOLOGIN,
162            Keyword::PASSWORD,
163            Keyword::REPLICATION,
164            Keyword::NOREPLICATION,
165            Keyword::SUPERUSER,
166            Keyword::NOSUPERUSER,
167            Keyword::VALID,
168        ]) {
169            Some(Keyword::BYPASSRLS) => RoleOption::BypassRLS(true),
170            Some(Keyword::NOBYPASSRLS) => RoleOption::BypassRLS(false),
171            Some(Keyword::CONNECTION) => {
172                self.expect_keyword(Keyword::LIMIT)?;
173                RoleOption::ConnectionLimit(Expr::Value(self.parse_number_value()?))
174            }
175            Some(Keyword::CREATEDB) => RoleOption::CreateDB(true),
176            Some(Keyword::NOCREATEDB) => RoleOption::CreateDB(false),
177            Some(Keyword::CREATEROLE) => RoleOption::CreateRole(true),
178            Some(Keyword::NOCREATEROLE) => RoleOption::CreateRole(false),
179            Some(Keyword::INHERIT) => RoleOption::Inherit(true),
180            Some(Keyword::NOINHERIT) => RoleOption::Inherit(false),
181            Some(Keyword::LOGIN) => RoleOption::Login(true),
182            Some(Keyword::NOLOGIN) => RoleOption::Login(false),
183            Some(Keyword::PASSWORD) => {
184                let password = if self.parse_keyword(Keyword::NULL) {
185                    Password::NullPassword
186                } else {
187                    Password::Password(Expr::Value(self.parse_value()?))
188                };
189                RoleOption::Password(password)
190            }
191            Some(Keyword::REPLICATION) => RoleOption::Replication(true),
192            Some(Keyword::NOREPLICATION) => RoleOption::Replication(false),
193            Some(Keyword::SUPERUSER) => RoleOption::SuperUser(true),
194            Some(Keyword::NOSUPERUSER) => RoleOption::SuperUser(false),
195            Some(Keyword::VALID) => {
196                self.expect_keyword(Keyword::UNTIL)?;
197                RoleOption::ValidUntil(Expr::Value(self.parse_value()?))
198            }
199            _ => self.expected("option", self.peek_token())?,
200        };
201
202        Ok(option)
203    }
204}