@@ -28,8 +28,9 @@ use serde::{Deserialize, Serialize};
28
28
#[ cfg( feature = "visitor" ) ]
29
29
use sqlparser_derive:: { Visit , VisitMut } ;
30
30
31
- use super :: { display_comma_separated, Expr , Ident , Password } ;
31
+ use super :: { display_comma_separated, Expr , Ident , Password , Spanned } ;
32
32
use crate :: ast:: { display_separated, ObjectName } ;
33
+ use crate :: tokenizer:: Span ;
33
34
34
35
/// An option in `ROLE` statement.
35
36
///
@@ -252,3 +253,113 @@ impl fmt::Display for SecondaryRoles {
252
253
}
253
254
}
254
255
}
256
+
257
+ /// CREATE ROLE statement
258
+ /// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-createrole.html)
259
+ #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
260
+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
261
+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
262
+ pub struct CreateRole {
263
+ pub names : Vec < ObjectName > ,
264
+ pub if_not_exists : bool ,
265
+ // Postgres
266
+ pub login : Option < bool > ,
267
+ pub inherit : Option < bool > ,
268
+ pub bypassrls : Option < bool > ,
269
+ pub password : Option < Password > ,
270
+ pub superuser : Option < bool > ,
271
+ pub create_db : Option < bool > ,
272
+ pub create_role : Option < bool > ,
273
+ pub replication : Option < bool > ,
274
+ pub connection_limit : Option < Expr > ,
275
+ pub valid_until : Option < Expr > ,
276
+ pub in_role : Vec < Ident > ,
277
+ pub in_group : Vec < Ident > ,
278
+ pub role : Vec < Ident > ,
279
+ pub user : Vec < Ident > ,
280
+ pub admin : Vec < Ident > ,
281
+ // MSSQL
282
+ pub authorization_owner : Option < ObjectName > ,
283
+ }
284
+
285
+ impl fmt:: Display for CreateRole {
286
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
287
+ write ! (
288
+ f,
289
+ "CREATE ROLE {if_not_exists}{names}{superuser}{create_db}{create_role}{inherit}{login}{replication}{bypassrls}" ,
290
+ if_not_exists = if self . if_not_exists { "IF NOT EXISTS " } else { "" } ,
291
+ names = display_separated( & self . names, ", " ) ,
292
+ superuser = match self . superuser {
293
+ Some ( true ) => " SUPERUSER" ,
294
+ Some ( false ) => " NOSUPERUSER" ,
295
+ None => ""
296
+ } ,
297
+ create_db = match self . create_db {
298
+ Some ( true ) => " CREATEDB" ,
299
+ Some ( false ) => " NOCREATEDB" ,
300
+ None => ""
301
+ } ,
302
+ create_role = match self . create_role {
303
+ Some ( true ) => " CREATEROLE" ,
304
+ Some ( false ) => " NOCREATEROLE" ,
305
+ None => ""
306
+ } ,
307
+ inherit = match self . inherit {
308
+ Some ( true ) => " INHERIT" ,
309
+ Some ( false ) => " NOINHERIT" ,
310
+ None => ""
311
+ } ,
312
+ login = match self . login {
313
+ Some ( true ) => " LOGIN" ,
314
+ Some ( false ) => " NOLOGIN" ,
315
+ None => ""
316
+ } ,
317
+ replication = match self . replication {
318
+ Some ( true ) => " REPLICATION" ,
319
+ Some ( false ) => " NOREPLICATION" ,
320
+ None => ""
321
+ } ,
322
+ bypassrls = match self . bypassrls {
323
+ Some ( true ) => " BYPASSRLS" ,
324
+ Some ( false ) => " NOBYPASSRLS" ,
325
+ None => ""
326
+ }
327
+ ) ?;
328
+ if let Some ( limit) = & self . connection_limit {
329
+ write ! ( f, " CONNECTION LIMIT {limit}" ) ?;
330
+ }
331
+ match & self . password {
332
+ Some ( Password :: Password ( pass) ) => write ! ( f, " PASSWORD {pass}" ) ?,
333
+ Some ( Password :: NullPassword ) => write ! ( f, " PASSWORD NULL" ) ?,
334
+ None => { }
335
+ } ;
336
+ if let Some ( until) = & self . valid_until {
337
+ write ! ( f, " VALID UNTIL {until}" ) ?;
338
+ }
339
+ if !self . in_role . is_empty ( ) {
340
+ write ! ( f, " IN ROLE {}" , display_comma_separated( & self . in_role) ) ?;
341
+ }
342
+ if !self . in_group . is_empty ( ) {
343
+ write ! ( f, " IN GROUP {}" , display_comma_separated( & self . in_group) ) ?;
344
+ }
345
+ if !self . role . is_empty ( ) {
346
+ write ! ( f, " ROLE {}" , display_comma_separated( & self . role) ) ?;
347
+ }
348
+ if !self . user . is_empty ( ) {
349
+ write ! ( f, " USER {}" , display_comma_separated( & self . user) ) ?;
350
+ }
351
+ if !self . admin . is_empty ( ) {
352
+ write ! ( f, " ADMIN {}" , display_comma_separated( & self . admin) ) ?;
353
+ }
354
+ if let Some ( owner) = & self . authorization_owner {
355
+ write ! ( f, " AUTHORIZATION {owner}" ) ?;
356
+ }
357
+ Ok ( ( ) )
358
+ }
359
+ }
360
+
361
+ impl Spanned for CreateRole {
362
+ fn span ( & self ) -> Span {
363
+ Span :: empty ( )
364
+ }
365
+ }
0 commit comments