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::{
21        AlterConnectorOwner, AlterPolicyOperation, AlterRoleOperation, Expr, Password, ResetConfig,
22        RoleOption, 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()?;
55        self.expect_keyword_is(Keyword::ON)?;
56        let table_name = self.parse_object_name(false)?;
57
58        if self.parse_keyword(Keyword::RENAME) {
59            self.expect_keyword_is(Keyword::TO)?;
60            let new_name = self.parse_identifier()?;
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    /// Parse an `ALTER CONNECTOR` statement
103    /// ```sql
104    /// ALTER CONNECTOR connector_name SET DCPROPERTIES(property_name=property_value, ...);
105    ///
106    /// ALTER CONNECTOR connector_name SET URL new_url;
107    ///
108    /// ALTER CONNECTOR connector_name SET OWNER [USER|ROLE] user_or_role;
109    /// ```
110    pub fn parse_alter_connector(&mut self) -> Result<Statement, ParserError> {
111        let name = self.parse_identifier()?;
112        self.expect_keyword_is(Keyword::SET)?;
113
114        let properties = match self.parse_options_with_keywords(&[Keyword::DCPROPERTIES])? {
115            properties if !properties.is_empty() => Some(properties),
116            _ => None,
117        };
118
119        let url = if self.parse_keyword(Keyword::URL) {
120            Some(self.parse_literal_string()?)
121        } else {
122            None
123        };
124
125        let owner = if self.parse_keywords(&[Keyword::OWNER, Keyword::USER]) {
126            let owner = self.parse_identifier()?;
127            Some(AlterConnectorOwner::User(owner))
128        } else if self.parse_keywords(&[Keyword::OWNER, Keyword::ROLE]) {
129            let owner = self.parse_identifier()?;
130            Some(AlterConnectorOwner::Role(owner))
131        } else {
132            None
133        };
134
135        Ok(Statement::AlterConnector {
136            name,
137            properties,
138            url,
139            owner,
140        })
141    }
142
143    fn parse_mssql_alter_role(&mut self) -> Result<Statement, ParserError> {
144        let role_name = self.parse_identifier()?;
145
146        let operation = if self.parse_keywords(&[Keyword::ADD, Keyword::MEMBER]) {
147            let member_name = self.parse_identifier()?;
148            AlterRoleOperation::AddMember { member_name }
149        } else if self.parse_keywords(&[Keyword::DROP, Keyword::MEMBER]) {
150            let member_name = self.parse_identifier()?;
151            AlterRoleOperation::DropMember { member_name }
152        } else if self.parse_keywords(&[Keyword::WITH, Keyword::NAME]) {
153            if self.consume_token(&Token::Eq) {
154                let role_name = self.parse_identifier()?;
155                AlterRoleOperation::RenameRole { role_name }
156            } else {
157                return self.expected("= after WITH NAME ", self.peek_token());
158            }
159        } else {
160            return self.expected("'ADD' or 'DROP' or 'WITH NAME'", self.peek_token());
161        };
162
163        Ok(Statement::AlterRole {
164            name: role_name,
165            operation,
166        })
167    }
168
169    fn parse_pg_alter_role(&mut self) -> Result<Statement, ParserError> {
170        let role_name = self.parse_identifier()?;
171
172        // [ IN DATABASE _`database_name`_ ]
173        let in_database = if self.parse_keywords(&[Keyword::IN, Keyword::DATABASE]) {
174            self.parse_object_name(false).ok()
175        } else {
176            None
177        };
178
179        let operation = if self.parse_keyword(Keyword::RENAME) {
180            if self.parse_keyword(Keyword::TO) {
181                let role_name = self.parse_identifier()?;
182                AlterRoleOperation::RenameRole { role_name }
183            } else {
184                return self.expected("TO after RENAME", self.peek_token());
185            }
186        // SET
187        } else if self.parse_keyword(Keyword::SET) {
188            let config_name = self.parse_object_name(false)?;
189            // FROM CURRENT
190            if self.parse_keywords(&[Keyword::FROM, Keyword::CURRENT]) {
191                AlterRoleOperation::Set {
192                    config_name,
193                    config_value: SetConfigValue::FromCurrent,
194                    in_database,
195                }
196            // { TO | = } { value | DEFAULT }
197            } else if self.consume_token(&Token::Eq) || self.parse_keyword(Keyword::TO) {
198                if self.parse_keyword(Keyword::DEFAULT) {
199                    AlterRoleOperation::Set {
200                        config_name,
201                        config_value: SetConfigValue::Default,
202                        in_database,
203                    }
204                } else if let Ok(expr) = self.parse_expr() {
205                    AlterRoleOperation::Set {
206                        config_name,
207                        config_value: SetConfigValue::Value(expr),
208                        in_database,
209                    }
210                } else {
211                    self.expected("config value", self.peek_token())?
212                }
213            } else {
214                self.expected("'TO' or '=' or 'FROM CURRENT'", self.peek_token())?
215            }
216        // RESET
217        } else if self.parse_keyword(Keyword::RESET) {
218            if self.parse_keyword(Keyword::ALL) {
219                AlterRoleOperation::Reset {
220                    config_name: ResetConfig::ALL,
221                    in_database,
222                }
223            } else {
224                let config_name = self.parse_object_name(false)?;
225                AlterRoleOperation::Reset {
226                    config_name: ResetConfig::ConfigName(config_name),
227                    in_database,
228                }
229            }
230        // option
231        } else {
232            // [ WITH ]
233            let _ = self.parse_keyword(Keyword::WITH);
234            // option
235            let mut options = vec![];
236            while let Some(opt) = self.maybe_parse(|parser| parser.parse_pg_role_option())? {
237                options.push(opt);
238            }
239            // check option
240            if options.is_empty() {
241                return self.expected("option", self.peek_token())?;
242            }
243
244            AlterRoleOperation::WithOptions { options }
245        };
246
247        Ok(Statement::AlterRole {
248            name: role_name,
249            operation,
250        })
251    }
252
253    fn parse_pg_role_option(&mut self) -> Result<RoleOption, ParserError> {
254        let option = match self.parse_one_of_keywords(&[
255            Keyword::BYPASSRLS,
256            Keyword::NOBYPASSRLS,
257            Keyword::CONNECTION,
258            Keyword::CREATEDB,
259            Keyword::NOCREATEDB,
260            Keyword::CREATEROLE,
261            Keyword::NOCREATEROLE,
262            Keyword::INHERIT,
263            Keyword::NOINHERIT,
264            Keyword::LOGIN,
265            Keyword::NOLOGIN,
266            Keyword::PASSWORD,
267            Keyword::REPLICATION,
268            Keyword::NOREPLICATION,
269            Keyword::SUPERUSER,
270            Keyword::NOSUPERUSER,
271            Keyword::VALID,
272        ]) {
273            Some(Keyword::BYPASSRLS) => RoleOption::BypassRLS(true),
274            Some(Keyword::NOBYPASSRLS) => RoleOption::BypassRLS(false),
275            Some(Keyword::CONNECTION) => {
276                self.expect_keyword_is(Keyword::LIMIT)?;
277                RoleOption::ConnectionLimit(Expr::Value(self.parse_number_value()?))
278            }
279            Some(Keyword::CREATEDB) => RoleOption::CreateDB(true),
280            Some(Keyword::NOCREATEDB) => RoleOption::CreateDB(false),
281            Some(Keyword::CREATEROLE) => RoleOption::CreateRole(true),
282            Some(Keyword::NOCREATEROLE) => RoleOption::CreateRole(false),
283            Some(Keyword::INHERIT) => RoleOption::Inherit(true),
284            Some(Keyword::NOINHERIT) => RoleOption::Inherit(false),
285            Some(Keyword::LOGIN) => RoleOption::Login(true),
286            Some(Keyword::NOLOGIN) => RoleOption::Login(false),
287            Some(Keyword::PASSWORD) => {
288                let password = if self.parse_keyword(Keyword::NULL) {
289                    Password::NullPassword
290                } else {
291                    Password::Password(Expr::Value(self.parse_value()?))
292                };
293                RoleOption::Password(password)
294            }
295            Some(Keyword::REPLICATION) => RoleOption::Replication(true),
296            Some(Keyword::NOREPLICATION) => RoleOption::Replication(false),
297            Some(Keyword::SUPERUSER) => RoleOption::SuperUser(true),
298            Some(Keyword::NOSUPERUSER) => RoleOption::SuperUser(false),
299            Some(Keyword::VALID) => {
300                self.expect_keyword_is(Keyword::UNTIL)?;
301                RoleOption::ValidUntil(Expr::Value(self.parse_value()?))
302            }
303            _ => self.expected("option", self.peek_token())?,
304        };
305
306        Ok(option)
307    }
308}