Skip to content

Commit dc086cd

Browse files
committed
Merge remote-tracking branch 'upstream/main' into feat_fix
2 parents 61839f9 + 6e44f8e commit dc086cd

File tree

61 files changed

+1138
-293
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+1138
-293
lines changed

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ pub enum OwnershipObject {
5252
UDF {
5353
name: String,
5454
},
55+
56+
Warehouse {
57+
id: String,
58+
},
5559
}
5660

5761
impl OwnershipObject {
@@ -80,6 +84,7 @@ impl fmt::Display for OwnershipObject {
8084
}
8185
OwnershipObject::UDF { name } => write!(f, "UDF {name}"),
8286
OwnershipObject::Stage { name } => write!(f, "STAGE {name}"),
87+
OwnershipObject::Warehouse { id } => write!(f, "Warehouse {id}"),
8388
}
8489
}
8590
}
@@ -119,6 +124,7 @@ impl KeyCodec for OwnershipObject {
119124
}
120125
OwnershipObject::Stage { name } => b.push_raw("stage-by-name").push_str(name),
121126
OwnershipObject::UDF { name } => b.push_raw("udf-by-name").push_str(name),
127+
OwnershipObject::Warehouse { id } => b.push_raw("warehouse-by-id").push_str(id),
122128
}
123129
}
124130

@@ -165,9 +171,13 @@ impl KeyCodec for OwnershipObject {
165171
let name = p.next_str()?;
166172
Ok(OwnershipObject::UDF { name })
167173
}
174+
"warehouse-by-id" => {
175+
let id = p.next_str()?;
176+
Ok(OwnershipObject::Warehouse { id })
177+
}
168178
_ => Err(kvapi::KeyError::InvalidSegment {
169179
i: p.index(),
170-
expect: "database-by-id|database-by-catalog-id|table-by-id|table-by-catalog-id|stage-by-name|udf-by-name"
180+
expect: "database-by-id|database-by-catalog-id|table-by-id|table-by-catalog-id|stage-by-name|udf-by-name|warehouse-by-id"
171181
.to_string(),
172182
got: q.to_string(),
173183
}),

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,22 @@ mod tests {
254254
let parsed = TenantOwnershipObjectIdent::from_str_key(&key).unwrap();
255255
assert_eq!(role_grantee, parsed);
256256
}
257+
258+
// warehouse
259+
{
260+
let role_grantee = TenantOwnershipObjectIdent::new_unchecked(
261+
Tenant::new_literal("test"),
262+
OwnershipObject::Warehouse {
263+
id: "n87s".to_string(),
264+
},
265+
);
266+
267+
let key = role_grantee.to_string_key();
268+
assert_eq!("__fd_object_owners/test/warehouse-by-id/n87s", key);
269+
270+
let parsed = TenantOwnershipObjectIdent::from_str_key(&key).unwrap();
271+
assert_eq!(role_grantee, parsed);
272+
}
257273
}
258274

259275
#[test]

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,9 @@ impl GrantObject {
111111
GrantObject::Stage(_) => {
112112
UserPrivilegeSet::available_privileges_on_stage(available_ownership)
113113
}
114-
GrantObject::Warehouse(_) => UserPrivilegeSet::available_privileges_on_warehouse(),
114+
GrantObject::Warehouse(_) => {
115+
UserPrivilegeSet::available_privileges_on_warehouse(available_ownership)
116+
}
115117
}
116118
}
117119

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

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ pub enum UserPrivilegeType {
7676
Write = 1 << 19,
7777
// Privilege to Create database
7878
CreateDatabase = 1 << 20,
79+
// Privilege to Create warehouse
80+
CreateWarehouse = 1 << 21,
7981
// Discard Privilege Type
8082
Set = 1 << 4,
8183
}
@@ -102,6 +104,7 @@ const ALL_PRIVILEGES: BitFlags<UserPrivilegeType> = make_bitflags!(
102104
| Read
103105
| Write
104106
| CreateDatabase
107+
| CreateWarehouse
105108
}
106109
);
107110

@@ -129,6 +132,7 @@ impl Display for UserPrivilegeType {
129132
UserPrivilegeType::Read => "Read",
130133
UserPrivilegeType::Write => "Write",
131134
UserPrivilegeType::CreateDatabase => "CREATE DATABASE",
135+
UserPrivilegeType::CreateWarehouse => "CREATE WAREHOUSE",
132136
})
133137
}
134138
}
@@ -166,6 +170,9 @@ impl From<databend_common_ast::ast::UserPrivilegeType> for UserPrivilegeType {
166170
databend_common_ast::ast::UserPrivilegeType::CreateDatabase => {
167171
UserPrivilegeType::CreateDatabase
168172
}
173+
databend_common_ast::ast::UserPrivilegeType::CreateWarehouse => {
174+
UserPrivilegeType::CreateWarehouse
175+
}
169176
databend_common_ast::ast::UserPrivilegeType::Set => UserPrivilegeType::Set,
170177
}
171178
}
@@ -199,8 +206,8 @@ impl UserPrivilegeSet {
199206
let database_privs = Self::available_privileges_on_database(false);
200207
let stage_privs_without_ownership = Self::available_privileges_on_stage(false);
201208
let udf_privs_without_ownership = Self::available_privileges_on_udf(false);
202-
let wh_privs_without_ownership = Self::available_privileges_on_warehouse();
203-
let privs = make_bitflags!(UserPrivilegeType::{ Usage | Super | CreateUser | DropUser | CreateRole | DropRole | CreateDatabase | Grant | CreateDataMask });
209+
let wh_privs_without_ownership = Self::available_privileges_on_warehouse(false);
210+
let privs = make_bitflags!(UserPrivilegeType::{ Usage | Super | CreateUser | DropUser | CreateRole | DropRole | CreateDatabase | Grant | CreateDataMask | CreateWarehouse });
204211
(database_privs.privileges
205212
| privs
206213
| stage_privs_without_ownership.privileges
@@ -234,8 +241,12 @@ impl UserPrivilegeSet {
234241
}
235242
}
236243

237-
pub fn available_privileges_on_warehouse() -> Self {
238-
make_bitflags!(UserPrivilegeType::{ Usage }).into()
244+
pub fn available_privileges_on_warehouse(available_ownership: bool) -> Self {
245+
if available_ownership {
246+
make_bitflags!(UserPrivilegeType::{ Usage | Ownership }).into()
247+
} else {
248+
make_bitflags!(UserPrivilegeType::{ Usage }).into()
249+
}
239250
}
240251

241252
pub fn available_privileges_on_udf(available_ownership: bool) -> Self {

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
@@ -88,6 +88,9 @@ impl FromToProto for mt::principal::OwnershipObject {
8888
pb::ownership_object::Object::Stage(pb::ownership_object::OwnershipStageObject {
8989
stage,
9090
}) => Ok(mt::principal::OwnershipObject::Stage { name: stage }),
91+
pb::ownership_object::Object::Warehouse(
92+
pb::ownership_object::OwnershipWarehouseObject { id },
93+
) => Ok(mt::principal::OwnershipObject::Warehouse { id }),
9194
}
9295
}
9396

@@ -123,6 +126,11 @@ impl FromToProto for mt::principal::OwnershipObject {
123126
stage: name.clone(),
124127
}),
125128
),
129+
mt::principal::OwnershipObject::Warehouse { id } => {
130+
Some(pb::ownership_object::Object::Warehouse(
131+
pb::ownership_object::OwnershipWarehouseObject { id: id.clone() },
132+
))
133+
}
126134
};
127135
Ok(pb::OwnershipObject {
128136
ver: VER,

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ const META_CHANGE_LOG: &[(u64, &str)] = &[
149149
(117, "2025-01-21: Add: config.proto: add disable_list_batch in WebhdfsConfig"),
150150
(118, "2025-01-22: Add: config.proto: add user_name in WebhdfsConfig"),
151151
(119, "2025-01-25: Add: virtual_column add alias_names and auto_generated field"),
152+
(120, "2025-02-11: Add: Add new UserPrivilege CreateWarehouse and new OwnershipObject::Warehouse"),
152153
// Dear developer:
153154
// If you're gonna add a new metadata version, you'll have to add a test for it.
154155
// You could just copy an existing test file(e.g., `../tests/it/v024_table_meta.rs`)

src/meta/proto-conv/tests/it/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,3 +117,4 @@ mod v116_marked_deleted_index_meta;
117117
mod v117_webhdfs_add_disable_list_batch;
118118
mod v118_webhdfs_add_user_name;
119119
mod v119_virtual_column;
120+
mod v120_warehouse_ownershipobject;
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
// Copyright 2023 Datafuse Labs.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
use std::collections::HashSet;
16+
17+
use chrono::DateTime;
18+
use chrono::Utc;
19+
use databend_common_meta_app as mt;
20+
use databend_common_meta_app::principal::OwnershipObject;
21+
use databend_common_meta_app::principal::UserGrantSet;
22+
use databend_common_meta_app::principal::UserPrivilegeType;
23+
use enumflags2::make_bitflags;
24+
use fastrace::func_name;
25+
26+
use crate::common;
27+
28+
// These bytes are built when a new version in introduced,
29+
// and are kept for backward compatibility test.
30+
//
31+
// *************************************************************
32+
// * These messages should never be updated, *
33+
// * only be added when a new version is added, *
34+
// * or be removed when an old version is no longer supported. *
35+
// *************************************************************
36+
//
37+
38+
#[test]
39+
fn test_decode_v120_grant_object() -> anyhow::Result<()> {
40+
let role_info_v120 = vec![
41+
10, 2, 114, 49, 18, 172, 1, 10, 21, 10, 8, 10, 0, 160, 6, 120, 168, 6, 24, 16, 128, 128,
42+
128, 1, 160, 6, 120, 168, 6, 24, 10, 31, 10, 21, 18, 13, 10, 7, 100, 101, 102, 97, 117,
43+
108, 116, 18, 2, 100, 98, 160, 6, 120, 168, 6, 24, 16, 2, 160, 6, 120, 168, 6, 24, 10, 35,
44+
10, 25, 26, 17, 10, 7, 100, 101, 102, 97, 117, 108, 116, 18, 2, 100, 98, 26, 2, 116, 98,
45+
160, 6, 120, 168, 6, 24, 16, 2, 160, 6, 120, 168, 6, 24, 10, 22, 10, 12, 34, 4, 10, 2, 102,
46+
49, 160, 6, 120, 168, 6, 24, 16, 1, 160, 6, 120, 168, 6, 24, 10, 24, 10, 12, 42, 4, 10, 2,
47+
115, 49, 160, 6, 120, 168, 6, 24, 16, 128, 128, 32, 160, 6, 120, 168, 6, 24, 10, 21, 10, 8,
48+
10, 0, 160, 6, 120, 168, 6, 24, 16, 254, 255, 191, 1, 160, 6, 120, 168, 6, 24, 160, 6, 120,
49+
168, 6, 24, 26, 23, 49, 57, 55, 48, 45, 48, 49, 45, 48, 49, 32, 48, 48, 58, 48, 48, 58, 48,
50+
48, 32, 85, 84, 67, 34, 23, 49, 57, 55, 48, 45, 48, 49, 45, 48, 49, 32, 48, 48, 58, 48, 48,
51+
58, 48, 48, 32, 85, 84, 67, 160, 6, 120, 168, 6, 24,
52+
];
53+
let want = || mt::principal::RoleInfo {
54+
name: "r1".to_string(),
55+
grants: UserGrantSet::new(
56+
vec![
57+
mt::principal::GrantEntry::new(
58+
mt::principal::GrantObject::Global,
59+
make_bitflags!(UserPrivilegeType::{CreateWarehouse}),
60+
),
61+
mt::principal::GrantEntry::new(
62+
mt::principal::GrantObject::Database("default".to_string(), "db".to_string()),
63+
make_bitflags!(UserPrivilegeType::{Create}),
64+
),
65+
mt::principal::GrantEntry::new(
66+
mt::principal::GrantObject::Table(
67+
"default".to_string(),
68+
"db".to_string(),
69+
"tb".to_string(),
70+
),
71+
make_bitflags!(UserPrivilegeType::{Create}),
72+
),
73+
mt::principal::GrantEntry::new(
74+
mt::principal::GrantObject::UDF("f1".to_string()),
75+
make_bitflags!(UserPrivilegeType::{Usage}),
76+
),
77+
mt::principal::GrantEntry::new(
78+
mt::principal::GrantObject::Stage("s1".to_string()),
79+
make_bitflags!(UserPrivilegeType::{Write}),
80+
),
81+
// test new global privilege CreateWarehouse
82+
mt::principal::GrantEntry::new(
83+
mt::principal::GrantObject::Global,
84+
make_bitflags!(UserPrivilegeType::{Create | Select | Insert | Update | Delete | Drop | Alter | Super | CreateUser | DropUser | CreateRole | DropRole | Grant | CreateStage | Set | CreateDataMask | Ownership | Read | Write | CreateWarehouse }),
85+
),
86+
],
87+
HashSet::new(),
88+
),
89+
created_on: DateTime::<Utc>::default(),
90+
update_on: DateTime::<Utc>::default(),
91+
};
92+
93+
common::test_pb_from_to(func_name!(), want())?;
94+
common::test_load_old(func_name!(), role_info_v120.as_slice(), 120, want())?;
95+
96+
Ok(())
97+
}
98+
99+
#[test]
100+
fn test_decode_v120_ownership() -> anyhow::Result<()> {
101+
let ownership_info_v120 = vec![
102+
10, 2, 114, 49, 18, 19, 42, 11, 10, 9, 97, 117, 110, 105, 113, 117, 101, 105, 100, 160, 6,
103+
120, 168, 6, 24, 160, 6, 120, 168, 6, 24,
104+
];
105+
106+
let want = || mt::principal::OwnershipInfo {
107+
role: "r1".to_string(),
108+
object: OwnershipObject::Warehouse {
109+
id: "auniqueid".to_string(),
110+
},
111+
};
112+
common::test_pb_from_to(func_name!(), want())?;
113+
common::test_load_old(func_name!(), ownership_info_v120.as_slice(), 120, want())?;
114+
115+
Ok(())
116+
}

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 OwnershipWarehouseObject {
50+
string id = 1;
51+
}
52+
4953
oneof object {
5054
OwnershipDatabaseObject database = 1;
5155
OwnershipTableObject table = 2;
5256
OwnershipUdfObject udf = 3;
5357
OwnershipStageObject stage = 4;
58+
OwnershipWarehouseObject warehouse = 5;
5459
}
5560
}

src/query/ast/src/ast/quote.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,16 @@ pub fn ident_needs_quote(ident: &str) -> bool {
5050
false
5151
}
5252

53-
pub fn display_ident(name: &str, quoted_ident_case_sensitive: bool, dialect: Dialect) -> String {
53+
pub fn display_ident(
54+
name: &str,
55+
force_quoted_ident: bool,
56+
quoted_ident_case_sensitive: bool,
57+
dialect: Dialect,
58+
) -> String {
5459
// Db-s -> "Db-s" ; dbs -> dbs
5560
if name.chars().any(|c| c.is_ascii_uppercase()) && quoted_ident_case_sensitive
5661
|| ident_needs_quote(name)
62+
|| force_quoted_ident
5763
{
5864
QuotedIdent(name, dialect.default_ident_quote()).to_string()
5965
} else {

src/query/ast/src/ast/statements/principal.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,8 @@ pub enum UserPrivilegeType {
150150
Write,
151151
// Privilege to Create database
152152
CreateDatabase,
153+
// Privilege to Create warehouse
154+
CreateWarehouse,
153155
// Discard Privilege Type
154156
Set,
155157
}
@@ -178,6 +180,7 @@ impl Display for UserPrivilegeType {
178180
UserPrivilegeType::Read => "Read",
179181
UserPrivilegeType::Write => "Write",
180182
UserPrivilegeType::CreateDatabase => "CREATE DATABASE",
183+
UserPrivilegeType::CreateWarehouse => "CREATE WAREHOUSE",
181184
})
182185
}
183186
}

src/query/ast/src/ast/statements/table.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ pub struct ShowCreateTableStmt {
7373
pub catalog: Option<Identifier>,
7474
pub database: Option<Identifier>,
7575
pub table: Identifier,
76+
pub with_quoted_ident: bool,
7677
}
7778

7879
impl Display for ShowCreateTableStmt {
@@ -84,7 +85,11 @@ impl Display for ShowCreateTableStmt {
8485
.iter()
8586
.chain(&self.database)
8687
.chain(Some(&self.table)),
87-
)
88+
)?;
89+
if self.with_quoted_ident {
90+
write!(f, " WITH QUOTED_IDENTIFIERS")?
91+
}
92+
Ok(())
8893
}
8994
}
9095

src/query/ast/src/ast/statements/user.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ pub enum GrantObjectName {
147147
Table(Option<String>, String),
148148
UDF(String),
149149
Stage(String),
150+
Warehouse(String),
150151
}
151152

152153
impl Display for GrantObjectName {
@@ -164,6 +165,7 @@ impl Display for GrantObjectName {
164165
}
165166
GrantObjectName::UDF(udf) => write!(f, " UDF {udf}"),
166167
GrantObjectName::Stage(stage) => write!(f, " STAGE {stage}"),
168+
GrantObjectName::Warehouse(w) => write!(f, " WAREHOUSE {w}"),
167169
}
168170
}
169171
}

src/query/ast/src/parser/common.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,10 @@ pub fn ident(i: Input) -> IResult<Identifier> {
8888
non_reserved_identifier(|token| token.is_reserved_ident(false))(i)
8989
}
9090

91+
pub fn grant_ident(i: Input) -> IResult<Identifier> {
92+
non_reserved_identifier(|token| token.is_grant_reserved_ident(false, true))(i)
93+
}
94+
9195
pub fn plain_ident(i: Input) -> IResult<Identifier> {
9296
plain_identifier(|token| token.is_reserved_ident(false))(i)
9397
}

0 commit comments

Comments
 (0)