Skip to content

Commit 71981a2

Browse files
authored
Merge pull request #6975 from lichuang/share_sql
feat: add Create Share sql support
2 parents d39a32d + 086adde commit 71981a2

File tree

17 files changed

+287
-0
lines changed

17 files changed

+287
-0
lines changed

common/ast/src/ast/statements/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ mod explain;
1919
mod insert;
2020
mod kill;
2121
mod presign;
22+
mod share;
2223
mod show;
2324
mod stage;
2425
mod statement;
@@ -33,6 +34,7 @@ pub use explain::*;
3334
pub use insert::*;
3435
pub use kill::*;
3536
pub use presign::*;
37+
pub use share::*;
3638
pub use show::*;
3739
pub use stage::*;
3840
pub use statement::*;
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Copyright 2022 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::fmt::Display;
16+
use std::fmt::Formatter;
17+
18+
use crate::ast::Identifier;
19+
20+
#[derive(Debug, Clone, PartialEq, Eq)]
21+
pub struct CreateShareStmt<'a> {
22+
pub if_not_exists: bool,
23+
pub share: Identifier<'a>,
24+
pub comment: Option<String>,
25+
}
26+
27+
impl Display for CreateShareStmt<'_> {
28+
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
29+
write!(f, "CREATE SHARE ")?;
30+
if self.if_not_exists {
31+
write!(f, "IF NOT EXISTS ")?;
32+
}
33+
write!(f, "{}", self.share)?;
34+
if let Some(comment) = &self.comment {
35+
write!(f, " COMMENT = '{comment}'")?;
36+
}
37+
Ok(())
38+
}
39+
}

common/ast/src/ast/statements/statement.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,9 @@ pub enum Statement<'a> {
157157
},
158158

159159
Presign(PresignStmt),
160+
161+
// share
162+
CreateShare(CreateShareStmt<'a>),
160163
}
161164

162165
#[derive(Debug, Clone, PartialEq)]
@@ -358,6 +361,7 @@ impl<'a> Display for Statement<'a> {
358361
Statement::DescribeStage { stage_name } => write!(f, "DESC STAGE {stage_name}")?,
359362
Statement::Call(stmt) => write!(f, "{stmt}")?,
360363
Statement::Presign(stmt) => write!(f, "{stmt}")?,
364+
Statement::CreateShare(stmt) => write!(f, "{stmt}")?,
361365
}
362366
Ok(())
363367
}

common/ast/src/parser/statement.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -741,6 +741,23 @@ pub fn statement(i: Input) -> IResult<StatementMsg> {
741741
},
742742
);
743743

744+
// share statements
745+
let create_share = map(
746+
rule! {
747+
CREATE ~ SHARE ~ (IF ~ NOT ~ EXISTS )? ~ #ident ~ ( COMMENT ~ "=" ~ #literal_string)?
748+
},
749+
|(_, _, opt_if_not_exists, share, comment_opt)| {
750+
Statement::CreateShare(CreateShareStmt {
751+
if_not_exists: opt_if_not_exists.is_some(),
752+
share,
753+
comment: match comment_opt {
754+
Some(opt) => Some(opt.2),
755+
None => None,
756+
},
757+
})
758+
},
759+
);
760+
744761
let statement_body = alt((
745762
rule!(
746763
#map(query, |query| Statement::Query(Box::new(query)))
@@ -826,6 +843,10 @@ pub fn statement(i: Input) -> IResult<StatementMsg> {
826843
rule!(
827844
#presign: "`PRESIGN [{DOWNLOAD | UPLOAD}] <location> [EXPIRE = 3600]`"
828845
),
846+
// share
847+
rule!(
848+
#create_share: "`CREATE SHARE <share_name> [ COMMENT = '<string_literal>' ]`"
849+
),
829850
));
830851

831852
map(

common/ast/src/parser/token.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -607,6 +607,8 @@ pub enum TokenKind {
607607
UPDATE,
608608
#[token("UPLOAD", ignore(ascii_case))]
609609
UPLOAD,
610+
#[token("SHARE", ignore(ascii_case))]
611+
SHARE,
610612
#[token("SUPER", ignore(ascii_case))]
611613
SUPER,
612614
#[token("STATUS", ignore(ascii_case))]

common/ast/tests/it/parser.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,8 @@ fn test_statement() {
252252
r#"PRESIGN @my_stage/path/to/file"#,
253253
r#"PRESIGN DOWNLOAD @my_stage/path/to/file"#,
254254
r#"PRESIGN UPLOAD @my_stage/path/to/file EXPIRE=7200"#,
255+
r#"CREATE SHARE t COMMENT='share comment';"#,
256+
r#"CREATE SHARE IF NOT EXISTS t;"#,
255257
];
256258

257259
for case in cases {

common/ast/tests/it/testdata/statement.txt

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5802,3 +5802,41 @@ Presign(
58025802
)
58035803

58045804

5805+
---------- Input ----------
5806+
CREATE SHARE t COMMENT='share comment';
5807+
---------- Output ---------
5808+
CREATE SHARE t COMMENT = 'share comment'
5809+
---------- AST ------------
5810+
CreateShare(
5811+
CreateShareStmt {
5812+
if_not_exists: false,
5813+
share: Identifier {
5814+
name: "t",
5815+
quote: None,
5816+
span: Ident(13..14),
5817+
},
5818+
comment: Some(
5819+
"share comment",
5820+
),
5821+
},
5822+
)
5823+
5824+
5825+
---------- Input ----------
5826+
CREATE SHARE IF NOT EXISTS t;
5827+
---------- Output ---------
5828+
CREATE SHARE IF NOT EXISTS t
5829+
---------- AST ------------
5830+
CreateShare(
5831+
CreateShareStmt {
5832+
if_not_exists: true,
5833+
share: Identifier {
5834+
name: "t",
5835+
quote: None,
5836+
span: Ident(27..28),
5837+
},
5838+
comment: None,
5839+
},
5840+
)
5841+
5842+

common/users/src/user_api.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,19 @@ use common_management::UdfMgr;
2929
use common_management::UserApi;
3030
use common_management::UserMgr;
3131
use common_meta_api::KVApi;
32+
use common_meta_store::MetaStore;
3233
use common_meta_store::MetaStoreProvider;
3334

3435
pub struct UserApiProvider {
36+
meta: MetaStore,
3537
client: Arc<dyn KVApi>,
3638
}
3739

3840
impl UserApiProvider {
3941
pub async fn create_global(conf: RpcClientConf) -> Result<Arc<UserApiProvider>> {
4042
let client = MetaStoreProvider::new(conf).try_get_meta_store().await?;
4143
Ok(Arc::new(UserApiProvider {
44+
meta: client.clone(),
4245
client: client.arc(),
4346
}))
4447
}
@@ -66,4 +69,8 @@ impl UserApiProvider {
6669
pub fn get_setting_api_client(&self, tenant: &str) -> Result<Arc<dyn SettingApi>> {
6770
Ok(Arc::new(SettingMgr::create(self.client.clone(), tenant)?))
6871
}
72+
73+
pub fn get_meta_store_client(&self) -> Arc<MetaStore> {
74+
Arc::new(self.meta.clone())
75+
}
6976
}

query/src/interpreters/interpreter_factory_v2.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ use crate::interpreters::interpreter_copy_v2::CopyInterpreterV2;
2525
use crate::interpreters::interpreter_presign::PresignInterpreter;
2626
use crate::interpreters::interpreter_table_create_v2::CreateTableInterpreterV2;
2727
use crate::interpreters::AlterUserInterpreter;
28+
use crate::interpreters::CreateShareInterpreter;
2829
use crate::interpreters::DropUserInterpreter;
2930
use crate::sessions::QueryContext;
3031
use crate::sql::plans::Plan;
@@ -250,6 +251,12 @@ impl InterpreterFactoryV2 {
250251
*p.clone(),
251252
)?)),
252253
Plan::Kill(p) => Ok(Arc::new(KillInterpreter::try_create(ctx, *p.clone())?)),
254+
255+
// share plans
256+
Plan::CreateShare(p) => Ok(Arc::new(CreateShareInterpreter::try_create(
257+
ctx,
258+
*p.clone(),
259+
)?)),
253260
}
254261
}
255262
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// Copyright 2022 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::sync::Arc;
16+
17+
use common_exception::Result;
18+
use common_meta_api::ShareApi;
19+
use common_streams::DataBlockStream;
20+
use common_streams::SendableDataBlockStream;
21+
22+
use crate::interpreters::Interpreter;
23+
use crate::sessions::QueryContext;
24+
use crate::sessions::TableContext;
25+
use crate::sql::plans::share::CreateSharePlan;
26+
27+
pub struct CreateShareInterpreter {
28+
ctx: Arc<QueryContext>,
29+
plan: CreateSharePlan,
30+
}
31+
32+
impl CreateShareInterpreter {
33+
pub fn try_create(ctx: Arc<QueryContext>, plan: CreateSharePlan) -> Result<Self> {
34+
Ok(CreateShareInterpreter { ctx, plan })
35+
}
36+
}
37+
38+
#[async_trait::async_trait]
39+
impl Interpreter for CreateShareInterpreter {
40+
fn name(&self) -> &str {
41+
"CreateShareInterpreter"
42+
}
43+
44+
async fn execute(&self) -> Result<SendableDataBlockStream> {
45+
let user_mgr = self.ctx.get_user_manager();
46+
let meta_api = user_mgr.get_meta_store_client();
47+
meta_api.create_share(self.plan.clone().into()).await?;
48+
49+
Ok(Box::pin(DataBlockStream::create(
50+
self.plan.schema(),
51+
None,
52+
vec![],
53+
)))
54+
}
55+
}

query/src/interpreters/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ mod interpreter_role_revoke;
4949
mod interpreter_select;
5050
mod interpreter_select_v2;
5151
mod interpreter_setting;
52+
mod interpreter_share_create;
5253
mod interpreter_show_databases;
5354
mod interpreter_show_functions;
5455
mod interpreter_show_grants;
@@ -129,6 +130,7 @@ pub use interpreter_role_revoke::RevokeRoleInterpreter;
129130
pub use interpreter_select::SelectInterpreter;
130131
pub use interpreter_select_v2::SelectInterpreterV2;
131132
pub use interpreter_setting::SettingInterpreter;
133+
pub use interpreter_share_create::CreateShareInterpreter;
132134
pub use interpreter_show_databases::ShowDatabasesInterpreter;
133135
pub use interpreter_show_functions::ShowFunctionsInterpreter;
134136
pub use interpreter_show_grants::ShowGrantsInterpreter;

query/src/sql/planner/binder/ddl/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
mod account;
1616
mod database;
17+
mod share;
1718
mod stage;
1819
mod table;
1920
mod view;
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Copyright 2022 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 common_ast::ast::*;
16+
use common_exception::Result;
17+
18+
use crate::sessions::TableContext;
19+
use crate::sql::binder::Binder;
20+
use crate::sql::plans::CreateSharePlan;
21+
use crate::sql::plans::Plan;
22+
23+
impl<'a> Binder {
24+
pub(in crate::sql::planner::binder) async fn bind_create_share(
25+
&mut self,
26+
stmt: &CreateShareStmt<'a>,
27+
) -> Result<Plan> {
28+
let CreateShareStmt {
29+
if_not_exists,
30+
share,
31+
comment,
32+
} = stmt;
33+
34+
let share = share.name.to_lowercase();
35+
36+
let plan = CreateSharePlan {
37+
if_not_exists: *if_not_exists,
38+
tenant: self.ctx.get_tenant(),
39+
share,
40+
comment: comment.as_ref().cloned(),
41+
};
42+
Ok(Plan::CreateShare(Box::new(plan)))
43+
}
44+
}

query/src/sql/planner/binder/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,11 @@ impl<'a> Binder {
293293
self.bind_kill_stmt(bind_context, kill_target, object_id.as_str())
294294
.await?
295295
}
296+
297+
Statement::CreateShare(stmt) => {
298+
self.bind_create_share(stmt).await?
299+
}
300+
296301
};
297302
Ok(plan)
298303
}

query/src/sql/planner/format/display_plan.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ impl Plan {
9393
Plan::SetVariable(p) => Ok(format!("{:?}", p)),
9494
Plan::UseDatabase(p) => Ok(format!("{:?}", p)),
9595
Plan::Kill(p) => Ok(format!("{:?}", p)),
96+
97+
Plan::CreateShare(p) => Ok(format!("{:?}", p)),
9698
}
9799
}
98100
}

0 commit comments

Comments
 (0)