diff --git a/common/ast/src/ast/statement.rs b/common/ast/src/ast/statement.rs index f0613c805d5c6..d5ff7223efce2 100644 --- a/common/ast/src/ast/statement.rs +++ b/common/ast/src/ast/statement.rs @@ -97,6 +97,7 @@ pub enum Statement<'a> { DropView(DropViewStmt<'a>), // User + ShowUsers, CreateUser(CreateUserStmt), AlterUser { // None means current user @@ -109,6 +110,7 @@ pub enum Statement<'a> { if_exists: bool, user: UserIdentity, }, + ShowRoles, CreateRole { if_not_exists: bool, role_name: String, @@ -924,6 +926,12 @@ impl<'a> Display for Statement<'a> { } write_period_separated_list(f, catalog.iter().chain(database).chain(Some(view)))?; } + Statement::ShowUsers => { + write!(f, "SHOW USERS")?; + } + Statement::ShowRoles => { + write!(f, "SHOW ROLES")?; + } Statement::CreateUser(CreateUserStmt { if_not_exists, user, diff --git a/common/ast/src/parser/statement.rs b/common/ast/src/parser/statement.rs index cfc3bbbaec552..8f5f3a4ca918e 100644 --- a/common/ast/src/parser/statement.rs +++ b/common/ast/src/parser/statement.rs @@ -374,6 +374,7 @@ pub fn statement(i: Input) -> IResult { }) }, ); + let show_users = value(Statement::ShowUsers, rule! { SHOW ~ USERS }); let create_user = map( rule! { CREATE ~ USER ~ ( IF ~ NOT ~ EXISTS )? @@ -421,6 +422,7 @@ pub fn statement(i: Input) -> IResult { user, }, ); + let show_roles = value(Statement::ShowRoles, rule! { SHOW ~ ROLES }); let create_role = map( rule! { CREATE ~ ROLE ~ ( IF ~ NOT ~ EXISTS )? ~ #literal_string @@ -627,9 +629,11 @@ pub fn statement(i: Input) -> IResult { | #alter_view : "`ALTER VIEW [.] AS SELECT ...`" ), rule!( - #create_user : "`CREATE USER [IF NOT EXISTS] ''@'hostname' IDENTIFIED [WITH ] [BY ] [WITH ...]`" + #show_users : "`SHOW USERS`" + | #create_user : "`CREATE USER [IF NOT EXISTS] ''@'hostname' IDENTIFIED [WITH ] [BY ] [WITH ...]`" | #alter_user : "`ALTER USER (''@'hostname' | USER()) [IDENTIFIED [WITH ] [BY ]] [WITH ...]`" | #drop_user : "`DROP USER [IF EXISTS] ''@'hostname'`" + | #show_roles : "`SHOW ROLES`" | #create_role : "`CREATE ROLE [IF NOT EXISTS] '']`" | #drop_role : "`DROP ROLE [IF EXISTS] ''`" | #create_udf : "`CREATE FUNCTION [IF NOT EXISTS] (, ...) -> [DESC = ]`" diff --git a/common/ast/src/parser/token.rs b/common/ast/src/parser/token.rs index 2ce3e40ac4347..0b06ecb60cd61 100644 --- a/common/ast/src/parser/token.rs +++ b/common/ast/src/parser/token.rs @@ -443,6 +443,8 @@ pub enum TokenKind { KILL, #[token("ROLE", ignore(ascii_case))] ROLE, + #[token("ROLES", ignore(ascii_case))] + ROLES, #[token("LEADING", ignore(ascii_case))] LEADING, #[token("LEFT", ignore(ascii_case))] @@ -621,6 +623,8 @@ pub enum TokenKind { USE, #[token("USER", ignore(ascii_case))] USER, + #[token("USERS", ignore(ascii_case))] + USERS, #[token("USING", ignore(ascii_case))] USING, #[token("VALUES", ignore(ascii_case))] diff --git a/query/src/interpreters/interpreter_factory.rs b/query/src/interpreters/interpreter_factory.rs index ead71775d2da8..d8611eaf49c68 100644 --- a/query/src/interpreters/interpreter_factory.rs +++ b/query/src/interpreters/interpreter_factory.rs @@ -120,12 +120,8 @@ impl InterpreterFactory { PlanNode::Show(ShowPlan::ShowSettings(_)) => { ShowSettingsInterpreter::try_create(ctx_clone) } - PlanNode::Show(ShowPlan::ShowUsers(v)) => { - ShowUsersInterpreter::try_create(ctx_clone, v) - } - PlanNode::Show(ShowPlan::ShowRoles(v)) => { - ShowRolesInterpreter::try_create(ctx_clone, v) - } + PlanNode::Show(ShowPlan::ShowUsers(_)) => ShowUsersInterpreter::try_create(ctx_clone), + PlanNode::Show(ShowPlan::ShowRoles(_)) => ShowRolesInterpreter::try_create(ctx_clone), PlanNode::Show(ShowPlan::ShowStages) => ShowStagesInterpreter::try_create(ctx_clone), // Database related transforms. diff --git a/query/src/interpreters/interpreter_factory_v2.rs b/query/src/interpreters/interpreter_factory_v2.rs index 9b492d5498b5d..7851a6e6812cb 100644 --- a/query/src/interpreters/interpreter_factory_v2.rs +++ b/query/src/interpreters/interpreter_factory_v2.rs @@ -60,7 +60,13 @@ impl InterpreterFactoryV2 { | DfStatement::ShowSettings(_) | DfStatement::CreateDatabase(_) | DfStatement::DropDatabase(_) + | DfStatement::ShowUsers(_) | DfStatement::CreateUser(_) + | DfStatement::DropUser(_) + | DfStatement::AlterUser(_) + | DfStatement::ShowRoles(_) + | DfStatement::CreateRole(_) + | DfStatement::DropRole(_) | DfStatement::AlterDatabase(_) ) } @@ -150,6 +156,7 @@ impl InterpreterFactoryV2 { Plan::DropView(drop_view) => DropViewInterpreter::try_create(ctx, *drop_view.clone()), // Users + Plan::ShowUsers => ShowUsersInterpreter::try_create(ctx), Plan::CreateUser(create_user) => { CreateUserInterpreter::try_create(ctx, *create_user.clone()) } @@ -159,6 +166,7 @@ impl InterpreterFactoryV2 { } // Roles + Plan::ShowRoles => ShowRolesInterpreter::try_create(ctx), Plan::CreateRole(create_role) => { CreateRoleInterpreter::try_create(ctx, *create_role.clone()) } diff --git a/query/src/interpreters/interpreter_show_roles.rs b/query/src/interpreters/interpreter_show_roles.rs index 66ec5beb80bf9..c4b4c75f59f60 100644 --- a/query/src/interpreters/interpreter_show_roles.rs +++ b/query/src/interpreters/interpreter_show_roles.rs @@ -17,7 +17,6 @@ use std::sync::Arc; use common_exception::ErrorCode; use common_exception::Result; use common_planners::PlanNode; -use common_planners::ShowRolesPlan; use common_streams::SendableDataBlockStream; use crate::interpreters::Interpreter; @@ -32,7 +31,7 @@ pub struct ShowRolesInterpreter { } impl ShowRolesInterpreter { - pub fn try_create(ctx: Arc, _plan: ShowRolesPlan) -> Result { + pub fn try_create(ctx: Arc) -> Result { Ok(Arc::new(ShowRolesInterpreter { ctx })) } diff --git a/query/src/interpreters/interpreter_show_users.rs b/query/src/interpreters/interpreter_show_users.rs index b7bd4d417c7ab..712688bb15b9c 100644 --- a/query/src/interpreters/interpreter_show_users.rs +++ b/query/src/interpreters/interpreter_show_users.rs @@ -17,7 +17,6 @@ use std::sync::Arc; use common_exception::ErrorCode; use common_exception::Result; use common_planners::PlanNode; -use common_planners::ShowUsersPlan; use common_streams::SendableDataBlockStream; use crate::interpreters::Interpreter; @@ -32,7 +31,7 @@ pub struct ShowUsersInterpreter { } impl ShowUsersInterpreter { - pub fn try_create(ctx: Arc, _plan: ShowUsersPlan) -> Result { + pub fn try_create(ctx: Arc) -> Result { Ok(Arc::new(ShowUsersInterpreter { ctx })) } diff --git a/query/src/sql/planner/binder/mod.rs b/query/src/sql/planner/binder/mod.rs index 835b0e91b9cab..937beebfa434b 100644 --- a/query/src/sql/planner/binder/mod.rs +++ b/query/src/sql/planner/binder/mod.rs @@ -141,6 +141,7 @@ impl<'a> Binder { if_exists: *if_exists, user: user.clone(), })), + Statement::ShowUsers => Plan::ShowUsers, Statement::AlterUser { user, auth_option, @@ -151,6 +152,7 @@ impl<'a> Binder { } // Roles + Statement::ShowRoles => Plan::ShowRoles, Statement::CreateRole { if_not_exists, role_name, diff --git a/query/src/sql/planner/format/display_plan.rs b/query/src/sql/planner/format/display_plan.rs index fb06bb58d0a37..9c30234ec34b8 100644 --- a/query/src/sql/planner/format/display_plan.rs +++ b/query/src/sql/planner/format/display_plan.rs @@ -64,11 +64,13 @@ impl Plan { Plan::DropView(drop_view) => Ok(format!("{:?}", drop_view)), // Users + Plan::ShowUsers => Ok("SHOW USERS".to_string()), Plan::CreateUser(create_user) => Ok(format!("{:?}", create_user)), Plan::DropUser(drop_user) => Ok(format!("{:?}", drop_user)), Plan::AlterUser(alter_user) => Ok(format!("{:?}", alter_user)), // Roles + Plan::ShowRoles => Ok("SHOW ROLES".to_string()), Plan::CreateRole(create_role) => Ok(format!("{:?}", create_role)), Plan::DropRole(drop_role) => Ok(format!("{:?}", drop_role)), diff --git a/query/src/sql/planner/plans/mod.rs b/query/src/sql/planner/plans/mod.rs index 27df2aee50810..76d974c364d62 100644 --- a/query/src/sql/planner/plans/mod.rs +++ b/query/src/sql/planner/plans/mod.rs @@ -98,10 +98,14 @@ pub enum Plan { AlterView(Box), DropView(Box), - // DCL + // Users + ShowUsers, AlterUser(Box), CreateUser(Box), DropUser(Box), + + // Roles + ShowRoles, CreateRole(Box), DropRole(Box), diff --git a/tests/suites/0_stateless/06_show/06_0007_show_roles.sql b/tests/suites/0_stateless/06_show/06_0007_show_roles.sql index 4749ee371cdc3..31f4de1856bf5 100644 --- a/tests/suites/0_stateless/06_show/06_0007_show_roles.sql +++ b/tests/suites/0_stateless/06_show/06_0007_show_roles.sql @@ -1,2 +1,3 @@ CREATE ROLE 'test'; SHOW ROLES; +DROP ROLE 'test'; diff --git a/tests/suites/0_stateless/06_show/06_0007_show_roles_v2.result b/tests/suites/0_stateless/06_show/06_0007_show_roles_v2.result new file mode 100644 index 0000000000000..0227f29245cdf --- /dev/null +++ b/tests/suites/0_stateless/06_show/06_0007_show_roles_v2.result @@ -0,0 +1,2 @@ +account_admin 0 +test 0 diff --git a/tests/suites/0_stateless/06_show/06_0007_show_roles_v2.sql b/tests/suites/0_stateless/06_show/06_0007_show_roles_v2.sql new file mode 100644 index 0000000000000..09ef9fa1751e6 --- /dev/null +++ b/tests/suites/0_stateless/06_show/06_0007_show_roles_v2.sql @@ -0,0 +1,4 @@ +set enable_planner_v2 = 1; +CREATE ROLE 'test'; +SHOW ROLES; +DROP ROLE 'test';