@@ -28,8 +28,9 @@ use serde::{Deserialize, Serialize};
2828#[ cfg( feature = "visitor" ) ]
2929use sqlparser_derive:: { Visit , VisitMut } ;
3030
31- use super :: { display_comma_separated, Expr , Ident , Password } ;
31+ use super :: { display_comma_separated, Expr , Ident , Password , Spanned } ;
3232use crate :: ast:: { display_separated, ObjectName } ;
33+ use crate :: tokenizer:: Span ;
3334
3435/// An option in `ROLE` statement.
3536///
@@ -252,3 +253,113 @@ impl fmt::Display for SecondaryRoles {
252253 }
253254 }
254255}
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