sqltk_parser/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::{
21        AlterPolicyOperation, AlterRoleOperation, Expr, Password, ResetConfig, RoleOption,
22        SetConfigValue, Statement,
23    },
24    dialect::{MsSqlDialect, PostgreSqlDialect},
25    keywords::Keyword,
26    tokenizer::Token,
27};
28
29impl Parser<'_> {
30    pub fn parse_alter_role(&mut self) -> Result<Statement, ParserError> {
31        if dialect_of!(self is PostgreSqlDialect) {
32            return self.parse_pg_alter_role();
33        } else if dialect_of!(self is MsSqlDialect) {
34            return self.parse_mssql_alter_role();
35        }
36
37        Err(ParserError::ParserError(
38            "ALTER ROLE is only support for PostgreSqlDialect, MsSqlDialect".into(),
39        ))
40    }
41
42    /// Parse ALTER POLICY statement
43    /// ```sql
44    /// ALTER POLICY policy_name ON table_name [ RENAME TO new_name ]
45    /// or
46    /// ALTER POLICY policy_name ON table_name
47    /// [ TO { role_name | PUBLIC | CURRENT_ROLE | CURRENT_USER | SESSION_USER } [, ...] ]
48    /// [ USING ( using_expression ) ]
49    /// [ WITH CHECK ( check_expression ) ]
50    /// ```
51    ///
52    /// [PostgreSQL](https://www.postgresql.org/docs/current/sql-alterpolicy.html)
53    pub fn parse_alter_policy(&mut self) -> Result<Statement, ParserError> {
54        let name = self.parse_identifier(false)?;
55        self.expect_keyword(Keyword::ON)?;
56        let table_name = self.parse_object_name(false)?;
57
58        if self.parse_keyword(Keyword::RENAME) {
59            self.expect_keyword(Keyword::TO)?;
60            let new_name = self.parse_identifier(false)?;
61            Ok(Statement::AlterPolicy {
62                name,
63                table_name,
64                operation: AlterPolicyOperation::Rename { new_name },
65            })
66        } else {
67            let to = if self.parse_keyword(Keyword::TO) {
68                Some(self.parse_comma_separated(|p| p.parse_owner())?)
69            } else {
70                None
71            };
72
73            let using = if self.parse_keyword(Keyword::USING) {
74                self.expect_token(&Token::LParen)?;
75                let expr = self.parse_expr()?;
76                self.expect_token(&Token::RParen)?;
77                Some(expr)
78            } else {
79                None
80            };
81
82            let with_check = if self.parse_keywords(&[Keyword::WITH, Keyword::CHECK]) {
83                self.expect_token(&Token::LParen)?;
84                let expr = self.parse_expr()?;
85                self.expect_token(&Token::RParen)?;
86                Some(expr)
87            } else {
88                None
89            };
90            Ok(Statement::AlterPolicy {
91                name,
92                table_name,
93                operation: AlterPolicyOperation::Apply {
94                    to,
95                    using,
96                    with_check,
97                },
98            })
99        }
100    }
101
102    fn parse_mssql_alter_role(&mut self) -> Result<Statement, ParserError> {
103        let role_name = self.parse_identifier(false)?;
104
105        let operation = if self.parse_keywords(&[Keyword::ADD, Keyword::MEMBER]) {
106            let member_name = self.parse_identifier(false)?;
107            AlterRoleOperation::AddMember { member_name }
108        } else if self.parse_keywords(&[Keyword::DROP, Keyword::MEMBER]) {
109            let member_name = self.parse_identifier(false)?;
110            AlterRoleOperation::DropMember { member_name }
111        } else if self.parse_keywords(&[Keyword::WITH, Keyword::NAME]) {
112            if self.consume_token(&Token::Eq) {
113                let role_name = self.parse_identifier(false)?;
114                AlterRoleOperation::RenameRole { role_name }
115            } else {
116                return self.expected("= after WITH NAME ", self.peek_token());
117            }
118        } else {
119            return self.expected("'ADD' or 'DROP' or 'WITH NAME'", self.peek_token());
120        };
121
122        Ok(Statement::AlterRole {
123            name: role_name,
124            operation,
125        })
126    }
127
128    fn parse_pg_alter_role(&mut self) -> Result<Statement, ParserError> {
129        let role_name = self.parse_identifier(false)?;
130
131        // [ IN DATABASE _`database_name`_ ]
132        let in_database = if self.parse_keywords(&[Keyword::IN, Keyword::DATABASE]) {
133            self.parse_object_name(false).ok()
134        } else {
135            None
136        };
137
138        let operation = if self.parse_keyword(Keyword::RENAME) {
139            if self.parse_keyword(Keyword::TO) {
140                let role_name = self.parse_identifier(false)?;
141                AlterRoleOperation::RenameRole { role_name }
142            } else {
143                return self.expected("TO after RENAME", self.peek_token());
144            }
145        // SET
146        } else if self.parse_keyword(Keyword::SET) {
147            let config_name = self.parse_object_name(false)?;
148            // FROM CURRENT
149            if self.parse_keywords(&[Keyword::FROM, Keyword::CURRENT]) {
150                AlterRoleOperation::Set {
151                    config_name,
152                    config_value: SetConfigValue::FromCurrent,
153                    in_database,
154                }
155            // { TO | = } { value | DEFAULT }
156            } else if self.consume_token(&Token::Eq) || self.parse_keyword(Keyword::TO) {
157                if self.parse_keyword(Keyword::DEFAULT) {
158                    AlterRoleOperation::Set {
159                        config_name,
160                        config_value: SetConfigValue::Default,
161                        in_database,
162                    }
163                } else if let Ok(expr) = self.parse_expr() {
164                    AlterRoleOperation::Set {
165                        config_name,
166                        config_value: SetConfigValue::Value(expr),
167                        in_database,
168                    }
169                } else {
170                    self.expected("config value", self.peek_token())?
171                }
172            } else {
173                self.expected("'TO' or '=' or 'FROM CURRENT'", self.peek_token())?
174            }
175        // RESET
176        } else if self.parse_keyword(Keyword::RESET) {
177            if self.parse_keyword(Keyword::ALL) {
178                AlterRoleOperation::Reset {
179                    config_name: ResetConfig::ALL,
180                    in_database,
181                }
182            } else {
183                let config_name = self.parse_object_name(false)?;
184                AlterRoleOperation::Reset {
185                    config_name: ResetConfig::ConfigName(config_name),
186                    in_database,
187                }
188            }
189        // option
190        } else {
191            // [ WITH ]
192            let _ = self.parse_keyword(Keyword::WITH);
193            // option
194            let mut options = vec![];
195            while let Some(opt) = self.maybe_parse(|parser| parser.parse_pg_role_option())? {
196                options.push(opt);
197            }
198            // check option
199            if options.is_empty() {
200                return self.expected("option", self.peek_token())?;
201            }
202
203            AlterRoleOperation::WithOptions { options }
204        };
205
206        Ok(Statement::AlterRole {
207            name: role_name,
208            operation,
209        })
210    }
211
212    fn parse_pg_role_option(&mut self) -> Result<RoleOption, ParserError> {
213        let option = match self.parse_one_of_keywords(&[
214            Keyword::BYPASSRLS,
215            Keyword::NOBYPASSRLS,
216            Keyword::CONNECTION,
217            Keyword::CREATEDB,
218            Keyword::NOCREATEDB,
219            Keyword::CREATEROLE,
220            Keyword::NOCREATEROLE,
221            Keyword::INHERIT,
222            Keyword::NOINHERIT,
223            Keyword::LOGIN,
224            Keyword::NOLOGIN,
225            Keyword::PASSWORD,
226            Keyword::REPLICATION,
227            Keyword::NOREPLICATION,
228            Keyword::SUPERUSER,
229            Keyword::NOSUPERUSER,
230            Keyword::VALID,
231        ]) {
232            Some(Keyword::BYPASSRLS) => RoleOption::BypassRLS(true),
233            Some(Keyword::NOBYPASSRLS) => RoleOption::BypassRLS(false),
234            Some(Keyword::CONNECTION) => {
235                self.expect_keyword(Keyword::LIMIT)?;
236                RoleOption::ConnectionLimit(Expr::Value(self.parse_number_value()?))
237            }
238            Some(Keyword::CREATEDB) => RoleOption::CreateDB(true),
239            Some(Keyword::NOCREATEDB) => RoleOption::CreateDB(false),
240            Some(Keyword::CREATEROLE) => RoleOption::CreateRole(true),
241            Some(Keyword::NOCREATEROLE) => RoleOption::CreateRole(false),
242            Some(Keyword::INHERIT) => RoleOption::Inherit(true),
243            Some(Keyword::NOINHERIT) => RoleOption::Inherit(false),
244            Some(Keyword::LOGIN) => RoleOption::Login(true),
245            Some(Keyword::NOLOGIN) => RoleOption::Login(false),
246            Some(Keyword::PASSWORD) => {
247                let password = if self.parse_keyword(Keyword::NULL) {
248                    Password::NullPassword
249                } else {
250                    Password::Password(Expr::Value(self.parse_value()?))
251                };
252                RoleOption::Password(password)
253            }
254            Some(Keyword::REPLICATION) => RoleOption::Replication(true),
255            Some(Keyword::NOREPLICATION) => RoleOption::Replication(false),
256            Some(Keyword::SUPERUSER) => RoleOption::SuperUser(true),
257            Some(Keyword::NOSUPERUSER) => RoleOption::SuperUser(false),
258            Some(Keyword::VALID) => {
259                self.expect_keyword(Keyword::UNTIL)?;
260                RoleOption::ValidUntil(Expr::Value(self.parse_value()?))
261            }
262            _ => self.expected("option", self.peek_token())?,
263        };
264
265        Ok(option)
266    }
267}