Skip to content

Commit

Permalink
support alter user in planner v2
Browse files Browse the repository at this point in the history
  • Loading branch information
TCeason committed Jun 7, 2022
1 parent 10e327d commit af701e3
Show file tree
Hide file tree
Showing 12 changed files with 136 additions and 1 deletion.
2 changes: 2 additions & 0 deletions common/ast/tests/it/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ fn test_statement() {
r#"select parse_json('{"k1": [0, 1, 2]}').k1[0];"#,
r#"create user 'test-e'@'localhost' identified by 'password';"#,
r#"drop user if exists 'test-j'@'localhost';"#,
r#"alter user 'test-e'@'localhost' identified by 'new-password';"#,
];

for case in cases {
Expand Down Expand Up @@ -173,6 +174,7 @@ fn test_statement_error() {
r#"alter database system x rename to db"#,
r#"create user 'test-e'@'localhost' identified bi 'password';"#,
r#"drop usar if exists 'test-j'@'localhost';"#,
r#"alter user 'test-e'@'localhost' identifie by 'new-password';"#,
];

for case in cases {
Expand Down
10 changes: 10 additions & 0 deletions common/ast/tests/it/testdata/statement-error.txt
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,13 @@ error:
| ^^^^ expected `DATABASE`, `SCHEMA`, `TABLE`, `VIEW`, `USER`, or `FUNCTION`


---------- Input ----------
alter user 'test-e'@'localhost' identifie by 'new-password';
---------- Output ---------
error:
--> SQL:1:33
|
1 | alter user 'test-e'@'localhost' identifie by 'new-password';
| ^^^^^^^^^ expected `IDENTIFIED`, `WITH`, or `;`


24 changes: 24 additions & 0 deletions common/ast/tests/it/testdata/statement.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2744,3 +2744,27 @@ DropUser {
}


---------- Input ----------
alter user 'test-e'@'localhost' identified by 'new-password';
---------- Output ---------
ALTER USER 'test-e'@'localhost' IDENTIFIED BY 'new-password'
---------- AST ------------
AlterUser {
user: Some(
UserIdentity {
username: "test-e",
hostname: "localhost",
},
),
auth_option: Some(
AuthOption {
auth_type: None,
password: Some(
"new-password",
),
},
),
role_options: [],
}


11 changes: 11 additions & 0 deletions common/meta/types/src/user_auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,17 @@ impl AuthInfo {
AuthInfo::new(new_auth_type, auth_string)
}

pub fn alter2(
&self,
auth_type: &Option<AuthType>,
auth_string: &Option<String>,
) -> Result<AuthInfo> {
let old_auth_type = self.get_type();
let new_auth_type = auth_type.clone().unwrap_or(old_auth_type);

AuthInfo::new(new_auth_type, auth_string)
}

pub fn get_type(&self) -> AuthType {
match self {
AuthInfo::None => AuthType::NoPassword,
Expand Down
4 changes: 4 additions & 0 deletions query/src/interpreters/interpreter_factory_v2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use super::SelectInterpreterV2;
use super::ShowMetricsInterpreter;
use super::ShowProcessListInterpreter;
use super::ShowSettingsInterpreter;
use crate::interpreters::AlterUserInterpreter;
use crate::interpreters::CreateUserInterpreter;
use crate::interpreters::DropUserInterpreter;
use crate::sessions::QueryContext;
Expand Down Expand Up @@ -71,6 +72,9 @@ impl InterpreterFactoryV2 {
Plan::ShowMetrics => ShowMetricsInterpreter::try_create(ctx),
Plan::ShowProcessList => ShowProcessListInterpreter::try_create(ctx),
Plan::ShowSettings => ShowSettingsInterpreter::try_create(ctx),
Plan::AlterUser(alter_user) => {
AlterUserInterpreter::try_create(ctx, *alter_user.clone())
}
Plan::CreateUser(create_user) => {
CreateUserInterpreter::try_create(ctx, *create_user.clone())
}
Expand Down
3 changes: 2 additions & 1 deletion query/src/sql/optimizer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ pub fn optimize(plan: Plan) -> Result<Plan> {
| Plan::CreateTable(_)
| Plan::CreateUser(_)
| Plan::CreateView(_)
| Plan::DropUser(_) => Ok(plan),
| Plan::DropUser(_)
| Plan::AlterUser(_) => Ok(plan),
}
}

Expand Down
52 changes: 52 additions & 0 deletions query/src/sql/planner/binder/ddl/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use common_ast::ast::AuthOption;
use common_ast::ast::CreateUserStmt;
use common_ast::ast::RoleOption;
use common_exception::Result;
use common_meta_types::AuthInfo;
use common_meta_types::UserIdentity;
use common_meta_types::UserOption;
use common_planners::AlterUserPlan;
use common_planners::CreateUserPlan;

use crate::sql::binder::Binder;
Expand All @@ -38,4 +42,52 @@ impl Binder {
};
Ok(Plan::CreateUser(Box::new(plan)))
}

pub(in crate::sql::planner::binder) async fn bind_alter_user(
&mut self,
user: &Option<UserIdentity>,
auth_option: &Option<AuthOption>,
role_options: &Vec<RoleOption>,
) -> Result<Plan> {
// None means current user
let user_info = if user.is_none() {
self.ctx.get_current_user()?
} else {
self.ctx
.get_user_manager()
.get_user(&self.ctx.get_tenant(), user.clone().unwrap())
.await?
};

// None means no change to make
let new_auth_info = if let Some(auth_option) = &auth_option {
let auth_info = user_info
.auth_info
.alter2(&auth_option.auth_type, &auth_option.password)?;
if user_info.auth_info == auth_info {
None
} else {
Some(auth_info)
}
} else {
None
};

let mut user_option = user_info.option.clone();
for option in role_options {
option.apply(&mut user_option);
}
let new_user_option = if user_option == user_info.option {
None
} else {
Some(user_option)
};
let plan = AlterUserPlan {
user: user_info.identity(),
auth_info: new_auth_info,
user_option: new_user_option,
};

Ok(Plan::AlterUser(Box::new(plan)))
}
}
10 changes: 10 additions & 0 deletions query/src/sql/planner/binder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,16 @@ impl<'a> Binder {
Statement::ShowMetrics => Ok(Plan::ShowMetrics),
Statement::ShowProcessList => Ok(Plan::ShowProcessList),
Statement::ShowSettings => Ok(Plan::ShowSettings),
Statement::AlterUser {
user,
auth_option,
role_options,
} => {
let plan = self
.bind_alter_user(user, auth_option, role_options)
.await?;
Ok(plan)
}
Statement::CreateUser(stmt) => {
let plan = self.bind_create_user(stmt).await?;
Ok(plan)
Expand Down
1 change: 1 addition & 0 deletions query/src/sql/planner/format/display_plan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ impl Plan {
Plan::ShowMetrics => Ok("SHOW METRICS".to_string()),
Plan::ShowProcessList => Ok("SHOW PROCESSLIST".to_string()),
Plan::ShowSettings => Ok("SHOW SETTINGS".to_string()),
Plan::AlterUser(alter_user) => Ok(format!("{:?}", alter_user)),
Plan::CreateUser(create_user) => Ok(format!("{:?}", create_user)),
Plan::CreateView(create_view) => Ok(format!("{:?}", create_view)),
Plan::DropUser(drop_user) => Ok(format!("{:?}", drop_user)),
Expand Down
2 changes: 2 additions & 0 deletions query/src/sql/planner/plans/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ mod sort;
pub use aggregate::AggregatePlan;
pub use apply::CrossApply;
use common_ast::ast::ExplainKind;
use common_planners::AlterUserPlan;
use common_planners::CreateTablePlan;
use common_planners::CreateUserPlan;
use common_planners::CreateViewPlan;
Expand Down Expand Up @@ -81,6 +82,7 @@ pub enum Plan {
ShowSettings,

// DCL
AlterUser(Box<AlterUserPlan>),
CreateUser(Box<CreateUserPlan>),
DropUser(Box<DropUserPlan>),
}
Empty file.
18 changes: 18 additions & 0 deletions tests/suites/0_stateless/05_ddl/05_0005_ddl_alter_user_v2.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
set enable_planner_v2=1;
DROP USER IF EXISTS 'test-e'@'localhost';
DROP USER IF EXISTS 'test-g'@'localhost';
DROP USER IF EXISTS 'test-h'@'localhost';
DROP USER IF EXISTS 'test-i'@'localhost';

CREATE USER 'test-e'@'localhost' IDENTIFIED BY 'password';
ALTER USER 'test-e'@'localhost' IDENTIFIED BY 'new-password';
ALTER USER 'test1'@'localhost' IDENTIFIED BY 'password'; -- {ErrorCode 2201}

CREATE USER 'test-g'@'localhost' IDENTIFIED WITH sha256_password BY 'password';
ALTER USER 'test-g'@'localhost' IDENTIFIED WITH sha256_password BY 'new-password';

CREATE USER 'test-h'@'localhost' IDENTIFIED WITH double_sha1_password BY 'password';
ALTER USER 'test-h'@'localhost' IDENTIFIED WITH double_sha1_password BY 'new-password';

CREATE USER 'test-i@localhost' IDENTIFIED WITH sha256_password BY 'password';
ALTER USER 'test-i@localhost' IDENTIFIED WITH sha256_password BY 'new-password';

0 comments on commit af701e3

Please sign in to comment.