Skip to content

Commit 1cb5d08

Browse files
committed
feat(query): task support ownership
1 parent f68c97e commit 1cb5d08

File tree

26 files changed

+433
-28
lines changed

26 files changed

+433
-28
lines changed

src/common/exception/src/exception_code.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,9 @@ build_exceptions! {
370370

371371
// sequence
372372
SequenceError(3101),
373+
374+
// Task
375+
UnknownTask(3201),
373376
}
374377

375378
// Storage errors [3001, 4000].

src/meta/app/src/principal/ownership_object.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ pub enum OwnershipObject {
5050
UDF {
5151
name: String,
5252
},
53+
54+
Task {
55+
name: String,
56+
},
5357
}
5458

5559
impl OwnershipObject {
@@ -97,6 +101,7 @@ impl KeyCodec for OwnershipObject {
97101
}
98102
OwnershipObject::Stage { name } => b.push_raw("stage-by-name").push_str(name),
99103
OwnershipObject::UDF { name } => b.push_raw("udf-by-name").push_str(name),
104+
OwnershipObject::Task { name } => b.push_raw("task-by-name").push_str(name),
100105
}
101106
}
102107

@@ -143,9 +148,13 @@ impl KeyCodec for OwnershipObject {
143148
let name = p.next_str()?;
144149
Ok(OwnershipObject::UDF { name })
145150
}
151+
"task-by-name" => {
152+
let name = p.next_str()?;
153+
Ok(OwnershipObject::Task { name })
154+
}
146155
_ => Err(kvapi::KeyError::InvalidSegment {
147156
i: p.index(),
148-
expect: "database-by-id|database-by-catalog-id|table-by-id|table-by-catalog-id|stage-by-name|udf-by-name"
157+
expect: "database-by-id|database-by-catalog-id|table-by-id|table-by-catalog-id|stage-by-name|udf-by-name|task-by-name"
149158
.to_string(),
150159
got: q.to_string(),
151160
}),

src/meta/app/src/principal/tenant_ownership_object_ident.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,22 @@ mod tests {
252252
let parsed = TenantOwnershipObjectIdent::from_str_key(&key).unwrap();
253253
assert_eq!(role_grantee, parsed);
254254
}
255+
256+
// udf
257+
{
258+
let role_grantee = TenantOwnershipObjectIdent::new_unchecked(
259+
Tenant::new_literal("test"),
260+
OwnershipObject::Task {
261+
name: "t1".to_string(),
262+
},
263+
);
264+
265+
let key = role_grantee.to_string_key();
266+
assert_eq!("__fd_object_owners/test/task-by-name/t1", key);
267+
268+
let parsed = TenantOwnershipObjectIdent::from_str_key(&key).unwrap();
269+
assert_eq!(role_grantee, parsed);
270+
}
255271
}
256272

257273
#[test]

src/meta/app/src/principal/user_grant.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ pub enum GrantObject {
3030
TableById(String, u64, u64),
3131
UDF(String),
3232
Stage(String),
33+
Task(String),
3334
}
3435

3536
impl GrantObject {
@@ -62,6 +63,7 @@ impl GrantObject {
6263
(GrantObject::Table(_, _, _), _) => false,
6364
(GrantObject::Stage(lstage), GrantObject::Stage(rstage)) => lstage == rstage,
6465
(GrantObject::UDF(udf), GrantObject::UDF(rudf)) => udf == rudf,
66+
(GrantObject::Task(task), GrantObject::Task(rtask)) => task == rtask,
6567
_ => false,
6668
}
6769
}
@@ -82,12 +84,18 @@ impl GrantObject {
8284
GrantObject::Stage(_) => {
8385
UserPrivilegeSet::available_privileges_on_stage(available_ownership)
8486
}
87+
GrantObject::Task(_) => {
88+
UserPrivilegeSet::available_privileges_on_task(available_ownership)
89+
}
8590
}
8691
}
8792

8893
pub fn catalog(&self) -> Option<String> {
8994
match self {
90-
GrantObject::Global | GrantObject::Stage(_) | GrantObject::UDF(_) => None,
95+
GrantObject::Global
96+
| GrantObject::Stage(_)
97+
| GrantObject::UDF(_)
98+
| GrantObject::Task(_) => None,
9199
GrantObject::Database(cat, _) | GrantObject::DatabaseById(cat, _) => Some(cat.clone()),
92100
GrantObject::Table(cat, _, _) | GrantObject::TableById(cat, _, _) => Some(cat.clone()),
93101
}
@@ -108,6 +116,7 @@ impl fmt::Display for GrantObject {
108116
}
109117
GrantObject::UDF(udf) => write!(f, "UDF {udf}"),
110118
GrantObject::Stage(stage) => write!(f, "STAGE {stage}"),
119+
GrantObject::Task(task) => write!(f, "task {task}"),
111120
}
112121
}
113122
}

src/meta/app/src/principal/user_privilege.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ pub enum UserPrivilegeType {
7575
Write = 1 << 19,
7676
// Privilege to Create database
7777
CreateDatabase = 1 << 20,
78+
// Privilege to Create task
79+
CreateTask = 1 << 21,
7880
// Discard Privilege Type
7981
Set = 1 << 4,
8082
}
@@ -101,6 +103,7 @@ const ALL_PRIVILEGES: BitFlags<UserPrivilegeType> = make_bitflags!(
101103
| Read
102104
| Write
103105
| CreateDatabase
106+
| CreateTask
104107
}
105108
);
106109

@@ -128,6 +131,7 @@ impl std::fmt::Display for UserPrivilegeType {
128131
UserPrivilegeType::Read => "Read",
129132
UserPrivilegeType::Write => "Write",
130133
UserPrivilegeType::CreateDatabase => "CREATE DATABASE",
134+
UserPrivilegeType::CreateTask => "CREATE TASK",
131135
})
132136
}
133137
}
@@ -160,10 +164,12 @@ impl UserPrivilegeSet {
160164
let database_privs = Self::available_privileges_on_database(false);
161165
let stage_privs_without_ownership = Self::available_privileges_on_stage(false);
162166
let udf_privs_without_ownership = Self::available_privileges_on_udf(false);
163-
let privs = make_bitflags!(UserPrivilegeType::{ Usage | Super | CreateUser | DropUser | CreateRole | DropRole | CreateDatabase | Grant | CreateDataMask });
167+
let task_privs_without_ownership = Self::available_privileges_on_task(false);
168+
let privs = make_bitflags!(UserPrivilegeType::{ Usage | Super | CreateUser | DropUser | CreateRole | DropRole | CreateDatabase | Grant | CreateDataMask | CreateTask });
164169
(database_privs.privileges
165170
| privs
166171
| stage_privs_without_ownership.privileges
172+
| task_privs_without_ownership.privileges
167173
| udf_privs_without_ownership.privileges)
168174
.into()
169175
}
@@ -201,6 +207,14 @@ impl UserPrivilegeSet {
201207
}
202208
}
203209

210+
pub fn available_privileges_on_task(available_ownership: bool) -> Self {
211+
if available_ownership {
212+
make_bitflags!(UserPrivilegeType::{ Drop | Alter | Ownership }).into()
213+
} else {
214+
make_bitflags!(UserPrivilegeType::{ Drop | Alter }).into()
215+
}
216+
}
217+
204218
// TODO: remove this, as ALL has different meanings on different objects
205219
pub fn all_privileges() -> Self {
206220
ALL_PRIVILEGES.into()

src/meta/proto-conv/src/ownership_from_to_protobuf_impl.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ impl FromToProto for mt::principal::OwnershipObject {
8282
Some(pb::ownership_object::Object::Stage(
8383
pb::ownership_object::OwnershipStageObject { stage },
8484
)) => Ok(mt::principal::OwnershipObject::Stage { name: stage }),
85+
Some(pb::ownership_object::Object::Task(
86+
pb::ownership_object::OwnershipTaskObject { task },
87+
)) => Ok(mt::principal::OwnershipObject::Task { name: task }),
8588
_ => Err(Incompatible {
8689
reason: "OwnershipObject cannot be None".to_string(),
8790
}),
@@ -115,6 +118,11 @@ impl FromToProto for mt::principal::OwnershipObject {
115118
pb::ownership_object::OwnershipUdfObject { udf: name.clone() },
116119
))
117120
}
121+
mt::principal::OwnershipObject::Task { name } => {
122+
Some(pb::ownership_object::Object::Task(
123+
pb::ownership_object::OwnershipTaskObject { task: name.clone() },
124+
))
125+
}
118126
mt::principal::OwnershipObject::Stage { name } => Some(
119127
pb::ownership_object::Object::Stage(pb::ownership_object::OwnershipStageObject {
120128
stage: name.clone(),

src/meta/proto-conv/src/user_from_to_protobuf_impl.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,9 @@ impl FromToProto for mt::principal::GrantObject {
180180
Some(pb::grant_object::Object::Stage(pb::grant_object::GrantStageObject { stage })) => {
181181
Ok(mt::principal::GrantObject::Stage(stage))
182182
}
183+
Some(pb::grant_object::Object::Task(pb::grant_object::GrantTaskObject { task })) => {
184+
Ok(mt::principal::GrantObject::Task(task))
185+
}
183186
_ => Err(Incompatible {
184187
reason: "GrantObject cannot be None".to_string(),
185188
}),
@@ -225,6 +228,9 @@ impl FromToProto for mt::principal::GrantObject {
225228
stage: stage.clone(),
226229
},
227230
)),
231+
mt::principal::GrantObject::Task(task) => Some(pb::grant_object::Object::Task(
232+
pb::grant_object::GrantTaskObject { task: task.clone() },
233+
)),
228234
};
229235
Ok(pb::GrantObject {
230236
ver: VER,

src/meta/proto-conv/src/util.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ const META_CHANGE_LOG: &[(u64, &str)] = &[
119119
(87, "2024-04-17: Add: UserOption::disabled"),
120120
(88, "2024-04-17: Add: SequenceMeta"),
121121
(89, "2024-04-19: Add: geometry_output_format settings"),
122+
(90, "2024-05-09: Add: GrantTaskObject"),
122123
// Dear developer:
123124
// If you're gonna add a new metadata version, you'll have to add a test for it.
124125
// You could just copy an existing test file(e.g., `../tests/it/v024_table_meta.rs`)

src/meta/protos/proto/ownership.proto

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,15 @@ message OwnershipObject {
4646
string stage = 1;
4747
}
4848

49+
message OwnershipTaskObject {
50+
string task = 1;
51+
}
52+
4953
oneof object {
5054
OwnershipDatabaseObject database = 1;
5155
OwnershipTableObject table = 2;
5256
OwnershipUdfObject udf = 3;
5357
OwnershipStageObject stage = 4;
58+
OwnershipTaskObject task = 5;
5459
}
5560
}

src/meta/protos/proto/user.proto

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@ message GrantObject {
7272
string udf = 1;
7373
}
7474

75+
message GrantTaskObject {
76+
string task = 1;
77+
}
78+
7579
message GrantStageObject {
7680
string stage = 1;
7781
}
@@ -84,6 +88,7 @@ message GrantObject {
8488
GrantStageObject stage = 5;
8589
GrantDatabaseIdObject databasebyid = 6;
8690
GrantTableIdObject tablebyid = 7;
91+
GrantTaskObject task = 8;
8792
}
8893
}
8994

0 commit comments

Comments
 (0)