Skip to content

Commit eb6472c

Browse files
authored
Merge pull request #7181 from lichuang/share_sql
feat: add show grant on object and show grant of share sql
2 parents ae5eac5 + 05f7d47 commit eb6472c

File tree

22 files changed

+456
-23
lines changed

22 files changed

+456
-23
lines changed

src/meta/api/src/share_api_impl.rs

+41-13
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,10 @@ impl<KV: KVApi> ShareApi for KV {
6868
debug!(req = debug(&req), "ShareApi: {}", func_name!());
6969

7070
// Get all outbound share accounts.
71-
let outbound_accounts = get_outbound_shared_accounts_by_tenant(self, &req.tenant).await?;
71+
let outbound_accounts = get_outbound_share_infos_by_tenant(self, &req.tenant).await?;
7272

7373
// Get all inbound share accounts.
74-
let inbound_accounts = get_inbound_shared_accounts_by_tenant(self, &req.tenant).await?;
74+
let inbound_accounts = get_inbound_share_infos_by_tenant(self, &req.tenant).await?;
7575

7676
Ok(ShowSharesReply {
7777
outbound_accounts,
@@ -759,11 +759,9 @@ impl<KV: KVApi> ShareApi for KV {
759759
&self,
760760
req: GetShareGrantTenantsReq,
761761
) -> MetaResult<GetShareGrantTenantsReply> {
762-
let reply = get_outbound_shared_accounts_by_name(self, &req.share_name).await?;
762+
let accounts = get_outbound_share_tenants_by_name(self, &req.share_name).await?;
763763

764-
Ok(GetShareGrantTenantsReply {
765-
accounts: reply.accounts.unwrap_or_default(),
766-
})
764+
Ok(GetShareGrantTenantsReply { accounts })
767765
}
768766

769767
// Return all the grant privileges of the object
@@ -920,7 +918,37 @@ async fn get_share_database_name(
920918
}
921919
}
922920

923-
async fn get_outbound_shared_accounts_by_name(
921+
async fn get_outbound_share_tenants_by_name(
922+
kv_api: &(impl KVApi + ?Sized),
923+
share_name: &ShareNameIdent,
924+
) -> Result<Vec<GetShareGrantTenants>, MetaError> {
925+
let res = get_share_or_err(kv_api, share_name, format!("get_share: {share_name}")).await?;
926+
let (_share_id_seq, share_id, _share_meta_seq, share_meta) = res;
927+
928+
let mut accounts = vec![];
929+
for account in share_meta.get_accounts() {
930+
let share_account_key = ShareAccountNameIdent {
931+
account: account.clone(),
932+
share_id,
933+
};
934+
935+
let (_seq, meta) = get_share_account_meta_or_err(
936+
kv_api,
937+
&share_account_key,
938+
format!("get_outbound_share_tenants_by_name's account: {share_id}/{account}"),
939+
)
940+
.await?;
941+
942+
accounts.push(GetShareGrantTenants {
943+
account,
944+
grant_on: meta.share_on,
945+
});
946+
}
947+
948+
Ok(accounts)
949+
}
950+
951+
async fn get_outbound_share_info_by_name(
924952
kv_api: &(impl KVApi + ?Sized),
925953
share_name: &ShareNameIdent,
926954
) -> Result<ShareAccountReply, MetaError> {
@@ -948,7 +976,7 @@ async fn get_outbound_shared_accounts_by_name(
948976
})
949977
}
950978

951-
async fn get_outbound_shared_accounts_by_tenant(
979+
async fn get_outbound_share_infos_by_tenant(
952980
kv_api: &(impl KVApi + ?Sized),
953981
tenant: &str,
954982
) -> Result<Vec<ShareAccountReply>, MetaError> {
@@ -961,7 +989,7 @@ async fn get_outbound_shared_accounts_by_tenant(
961989
let share_name_keys = list_keys(kv_api, &tenant_share_name_key).await?;
962990

963991
for share_name in share_name_keys {
964-
let reply = get_outbound_shared_accounts_by_name(kv_api, &share_name).await;
992+
let reply = get_outbound_share_info_by_name(kv_api, &share_name).await;
965993
if let Ok(reply) = reply {
966994
outbound_share_accounts.push(reply)
967995
}
@@ -970,7 +998,7 @@ async fn get_outbound_shared_accounts_by_tenant(
970998
Ok(outbound_share_accounts)
971999
}
9721000

973-
async fn get_inbound_shared_accounts_by_tenant(
1001+
async fn get_inbound_share_infos_by_tenant(
9741002
kv_api: &(impl KVApi + ?Sized),
9751003
tenant: &String,
9761004
) -> Result<Vec<ShareAccountReply>, MetaError> {
@@ -986,14 +1014,14 @@ async fn get_inbound_shared_accounts_by_tenant(
9861014
let (_share_meta_seq, share_meta) = get_share_meta_by_id_or_err(
9871015
kv_api,
9881016
share_id,
989-
format!("get_inbound_shared_accounts_by_tenant: {}", share_id),
1017+
format!("get_inbound_share_infos_by_tenant: {}", share_id),
9901018
)
9911019
.await?;
9921020

9931021
let (_seq, share_name) = get_share_id_to_name_or_err(
9941022
kv_api,
9951023
share_id,
996-
format!("get_inbound_shared_accounts_by_tenant: {}", share_id),
1024+
format!("get_inbound_share_infos_by_tenant: {}", share_id),
9971025
)
9981026
.await?;
9991027
let database_name = get_share_database_name(kv_api, &share_meta, &share_name).await?;
@@ -1006,7 +1034,7 @@ async fn get_inbound_shared_accounts_by_tenant(
10061034
kv_api,
10071035
&share_account_key,
10081036
format!(
1009-
"get_inbound_shared_accounts_by_tenant's account: {}/{}",
1037+
"get_inbound_share_infos_by_tenant's account: {}/{}",
10101038
share_id, tenant
10111039
),
10121040
)

src/meta/api/src/share_api_test_suite.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ impl ShareApiTestSuite {
260260
assert!(resp.is_ok());
261261
let resp = resp.unwrap();
262262
assert_eq!(resp.accounts.len(), 1);
263-
assert_eq!(resp.accounts[0], account.to_string());
263+
assert_eq!(resp.accounts[0].account, account.to_string());
264264
}
265265

266266
info!("--- share tenant2.share2 to tenant1");

src/meta/app/src/share/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ pub use share::GetObjectGrantPrivilegesReply;
2525
pub use share::GetObjectGrantPrivilegesReq;
2626
pub use share::GetShareGrantObjectReply;
2727
pub use share::GetShareGrantObjectReq;
28+
pub use share::GetShareGrantTenants;
2829
pub use share::GetShareGrantTenantsReply;
2930
pub use share::GetShareGrantTenantsReq;
3031
pub use share::GrantShareObjectReply;

src/meta/app/src/share/share.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -202,9 +202,15 @@ pub struct GetShareGrantTenantsReq {
202202
pub share_name: ShareNameIdent,
203203
}
204204

205+
#[derive(serde::Serialize, serde::Deserialize, Clone, Debug, PartialEq, Eq)]
206+
pub struct GetShareGrantTenants {
207+
pub account: String,
208+
pub grant_on: DateTime<Utc>,
209+
}
210+
205211
#[derive(serde::Serialize, serde::Deserialize, Clone, Debug, PartialEq, Eq)]
206212
pub struct GetShareGrantTenantsReply {
207-
pub accounts: Vec<String>,
213+
pub accounts: Vec<GetShareGrantTenants>,
208214
}
209215

210216
#[derive(serde::Serialize, serde::Deserialize, Clone, Debug, PartialEq, Eq)]

src/query/ast/src/ast/statements/share.rs

+26
Original file line numberDiff line numberDiff line change
@@ -151,3 +151,29 @@ impl Display for ShowSharesStmt {
151151
Ok(())
152152
}
153153
}
154+
155+
#[derive(Debug, Clone, PartialEq, Eq)]
156+
pub struct ShowObjectGrantPrivilegesStmt {
157+
pub object: ShareGrantObjectName,
158+
}
159+
160+
impl Display for ShowObjectGrantPrivilegesStmt {
161+
fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
162+
write!(f, "SHOW GRANTS ON {}", self.object)?;
163+
164+
Ok(())
165+
}
166+
}
167+
168+
#[derive(Debug, Clone, PartialEq, Eq)]
169+
pub struct ShowGrantsOfShareStmt {
170+
pub share_name: String,
171+
}
172+
173+
impl Display for ShowGrantsOfShareStmt {
174+
fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
175+
write!(f, "SHOW GRANTS OF SHARE {}", self.share_name)?;
176+
177+
Ok(())
178+
}
179+
}

src/query/ast/src/ast/statements/statement.rs

+4
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,8 @@ pub enum Statement<'a> {
166166
AlterShareTenants(AlterShareTenantsStmt<'a>),
167167
DescShare(DescShareStmt<'a>),
168168
ShowShares(ShowSharesStmt),
169+
ShowObjectGrantPrivileges(ShowObjectGrantPrivilegesStmt),
170+
ShowGrantsOfShare(ShowGrantsOfShareStmt),
169171
}
170172

171173
#[derive(Debug, Clone, PartialEq)]
@@ -376,6 +378,8 @@ impl<'a> Display for Statement<'a> {
376378
Statement::AlterShareTenants(stmt) => write!(f, "{stmt}")?,
377379
Statement::DescShare(stmt) => write!(f, "{stmt}")?,
378380
Statement::ShowShares(stmt) => write!(f, "{stmt}")?,
381+
Statement::ShowObjectGrantPrivileges(stmt) => write!(f, "{stmt}")?,
382+
Statement::ShowGrantsOfShare(stmt) => write!(f, "{stmt}")?,
379383
}
380384
Ok(())
381385
}

src/query/ast/src/parser/statement.rs

+48-4
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ use crate::rule;
3737
use crate::util::*;
3838
use crate::ErrorKind;
3939

40+
pub enum ShowGrantOption {
41+
PrincipalIdentity(PrincipalIdentity),
42+
ShareGrantObjectName(ShareGrantObjectName),
43+
ShareName(String),
44+
}
45+
4046
pub fn statement(i: Input) -> IResult<StatementMsg> {
4147
let explain = map_res(
4248
rule! {
@@ -544,10 +550,19 @@ pub fn statement(i: Input) -> IResult<StatementMsg> {
544550
);
545551
let show_grants = map(
546552
rule! {
547-
SHOW ~ GRANTS ~ (FOR ~ #grant_option)?
553+
SHOW ~ GRANTS ~ #show_grant_option?
548554
},
549-
|(_, _, opt_principal)| Statement::ShowGrants {
550-
principal: opt_principal.map(|(_, principal)| principal),
555+
|(_, _, show_grant_option)| match show_grant_option {
556+
Some(ShowGrantOption::PrincipalIdentity(principal)) => Statement::ShowGrants {
557+
principal: Some(principal),
558+
},
559+
Some(ShowGrantOption::ShareGrantObjectName(object)) => {
560+
Statement::ShowObjectGrantPrivileges(ShowObjectGrantPrivilegesStmt { object })
561+
}
562+
Some(ShowGrantOption::ShareName(share_name)) => {
563+
Statement::ShowGrantsOfShare(ShowGrantsOfShareStmt { share_name })
564+
}
565+
None => Statement::ShowGrants { principal: None },
551566
},
552567
);
553568
let revoke = map(
@@ -906,7 +921,7 @@ pub fn statement(i: Input) -> IResult<StatementMsg> {
906921
),
907922
rule!(
908923
#grant : "`GRANT { ROLE <role_name> | schemaObjectPrivileges | ALL [ PRIVILEGES ] ON <privileges_level> } TO { [ROLE <role_name>] | [USER] <user> }`"
909-
| #show_grants : "`SHOW GRANTS [FOR { ROLE <role_name> | [USER] <user> }]`"
924+
| #show_grants : "`SHOW GRANTS {FOR { ROLE <role_name> | USER <user> }] | ON {DATABASE <db_name> | TABLE <db_name>.<table_name>} }`"
910925
| #revoke : "`REVOKE { ROLE <role_name> | schemaObjectPrivileges | ALL [ PRIVILEGES ] ON <privileges_level> } FROM { [ROLE <role_name>] | [USER] <user> }`"
911926
),
912927
rule!(
@@ -1146,6 +1161,35 @@ pub fn grant_level(i: Input) -> IResult<AccountMgrLevel> {
11461161
)(i)
11471162
}
11481163

1164+
pub fn show_grant_option(i: Input) -> IResult<ShowGrantOption> {
1165+
let grant_role = map(
1166+
rule! {
1167+
FOR ~ #grant_option
1168+
},
1169+
|(_, opt_principal)| ShowGrantOption::PrincipalIdentity(opt_principal),
1170+
);
1171+
1172+
let share_object_name = map(
1173+
rule! {
1174+
ON ~ #grant_share_object_name
1175+
},
1176+
|(_, object_name)| ShowGrantOption::ShareGrantObjectName(object_name),
1177+
);
1178+
1179+
let share_name = map(
1180+
rule! {
1181+
OF ~ SHARE ~ #ident
1182+
},
1183+
|(_, _, share_name)| ShowGrantOption::ShareName(share_name.to_string()),
1184+
);
1185+
1186+
rule!(
1187+
#grant_role: "FOR { ROLE <role_name> | [USER] <user> }"
1188+
| #share_object_name: "ON {DATABASE <db_name> | TABLE <db_name>.<table_name>}"
1189+
| #share_name: "OF SHARE <share_name>"
1190+
)(i)
1191+
}
1192+
11491193
pub fn grant_option(i: Input) -> IResult<PrincipalIdentity> {
11501194
let role = map(
11511195
rule! {

src/query/ast/src/parser/token.rs

+4
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,8 @@ pub enum TokenKind {
513513
NULL,
514514
#[token("OBJECT", ignore(ascii_case))]
515515
OBJECT,
516+
#[token("OF", ignore(ascii_case))]
517+
OF,
516518
#[token("OFFSET", ignore(ascii_case))]
517519
OFFSET,
518520
#[token("ON", ignore(ascii_case))]
@@ -917,6 +919,7 @@ impl TokenKind {
917919
| TokenKind::LIMIT
918920
| TokenKind::OFFSET
919921
| TokenKind::ON
922+
| TokenKind::OF
920923
| TokenKind::ORDER
921924
// | TokenKind::PRECISION
922925
// | TokenKind::RETURNING
@@ -1027,6 +1030,7 @@ impl TokenKind {
10271030
// | TokenKind::NOTNULL
10281031
| TokenKind::OFFSET
10291032
| TokenKind::ON
1033+
| TokenKind::OF
10301034
| TokenKind::ORDER
10311035
// | TokenKind::OVERLAPS
10321036
// | TokenKind::RETURNING

src/query/ast/tests/it/parser.rs

+3
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,9 @@ fn test_statement() {
271271
r#"DESC SHARE b;"#,
272272
r#"DESCRIBE SHARE b;"#,
273273
r#"SHOW SHARES;"#,
274+
r#"SHOW GRANTS ON TABLE db1.tb1;"#,
275+
r#"SHOW GRANTS ON DATABASE db;"#,
276+
r#"SHOW GRANTS OF SHARE t;"#,
274277
];
275278

276279
for case in cases {

src/query/ast/tests/it/testdata/statement.txt

+41
Original file line numberDiff line numberDiff line change
@@ -6222,3 +6222,44 @@ ShowShares(
62226222
)
62236223

62246224

6225+
---------- Input ----------
6226+
SHOW GRANTS ON TABLE db1.tb1;
6227+
---------- Output ---------
6228+
SHOW GRANTS ON TABLE db1.tb1
6229+
---------- AST ------------
6230+
ShowObjectGrantPrivileges(
6231+
ShowObjectGrantPrivilegesStmt {
6232+
object: Table(
6233+
"db1",
6234+
"tb1",
6235+
),
6236+
},
6237+
)
6238+
6239+
6240+
---------- Input ----------
6241+
SHOW GRANTS ON DATABASE db;
6242+
---------- Output ---------
6243+
SHOW GRANTS ON DATABASE db
6244+
---------- AST ------------
6245+
ShowObjectGrantPrivileges(
6246+
ShowObjectGrantPrivilegesStmt {
6247+
object: Database(
6248+
"db",
6249+
),
6250+
},
6251+
)
6252+
6253+
6254+
---------- Input ----------
6255+
SHOW GRANTS OF SHARE t;
6256+
---------- Output ---------
6257+
SHOW GRANTS OF SHARE t
6258+
---------- AST ------------
6259+
ShowGrantsOfShare(
6260+
ShowGrantsOfShareStmt {
6261+
share_name: "t",
6262+
},
6263+
)
6264+
6265+

src/query/service/src/interpreters/interpreter_factory_v2.rs

+6
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,12 @@ impl InterpreterFactoryV2 {
272272
ctx,
273273
*p.clone(),
274274
)?)),
275+
Plan::ShowObjectGrantPrivileges(p) => Ok(Arc::new(
276+
ShowObjectGrantPrivilegesInterpreter::try_create(ctx, *p.clone())?,
277+
)),
278+
Plan::ShowGrantTenantsOfShare(p) => Ok(Arc::new(
279+
ShowGrantTenantsOfShareInterpreter::try_create(ctx, *p.clone())?,
280+
)),
275281
}
276282
}
277283
}

0 commit comments

Comments
 (0)