Skip to content

Commit b73a9eb

Browse files
authored
feat(query): support alter table/database refresh cache (#17841)
* feat(query): support alter table/database refresh cache 1. ALTER TABLE <table_name> REFRESH CACHE 2. ALTER DATABASE <database_name> REFRESH CACHE Note: Only Iceberg catalog support refresh cache * add refresh_table/database api * directly return Ok in trait
1 parent d30697f commit b73a9eb

File tree

25 files changed

+378
-4
lines changed

25 files changed

+378
-4
lines changed

src/query/ast/src/ast/statements/database.rs

+4
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,9 @@ impl Display for AlterDatabaseStmt {
166166
AlterDatabaseAction::RenameDatabase { new_db } => {
167167
write!(f, " RENAME TO {new_db}")?;
168168
}
169+
AlterDatabaseAction::RefreshDatabaseCache => {
170+
write!(f, " REFRESH CACHE")?;
171+
}
169172
}
170173

171174
Ok(())
@@ -175,6 +178,7 @@ impl Display for AlterDatabaseStmt {
175178
#[derive(Debug, Clone, PartialEq, Eq, Drive, DriveMut)]
176179
pub enum AlterDatabaseAction {
177180
RenameDatabase { new_db: Identifier },
181+
RefreshDatabaseCache,
178182
}
179183

180184
#[derive(Debug, Clone, PartialEq, Eq, Drive, DriveMut)]

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

+4
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,7 @@ pub enum AlterTableAction {
465465
UnsetOptions {
466466
targets: Vec<Identifier>,
467467
},
468+
RefreshTableCache,
468469
}
469470

470471
impl Display for AlterTableAction {
@@ -534,6 +535,9 @@ impl Display for AlterTableAction {
534535
write!(f, ")")?;
535536
}
536537
}
538+
AlterTableAction::RefreshTableCache => {
539+
write!(f, "REFRESH CACHE")?;
540+
}
537541
};
538542
Ok(())
539543
}

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

+17-1
Original file line numberDiff line numberDiff line change
@@ -3719,15 +3719,23 @@ pub fn create_table_source(i: Input) -> IResult<CreateTableSource> {
37193719
}
37203720

37213721
pub fn alter_database_action(i: Input) -> IResult<AlterDatabaseAction> {
3722-
let mut rename_database = map(
3722+
let rename_database = map(
37233723
rule! {
37243724
RENAME ~ TO ~ #ident
37253725
},
37263726
|(_, _, new_db)| AlterDatabaseAction::RenameDatabase { new_db },
37273727
);
37283728

3729+
let refresh_cache = map(
3730+
rule! {
3731+
REFRESH ~ CACHE
3732+
},
3733+
|(_, _)| AlterDatabaseAction::RefreshDatabaseCache,
3734+
);
3735+
37293736
rule!(
37303737
#rename_database
3738+
| #refresh_cache
37313739
)(i)
37323740
}
37333741

@@ -3939,6 +3947,13 @@ pub fn alter_table_action(i: Input) -> IResult<AlterTableAction> {
39393947
|(_, _, targets)| AlterTableAction::UnsetOptions { targets },
39403948
);
39413949

3950+
let refresh_cache = map(
3951+
rule! {
3952+
REFRESH ~ CACHE
3953+
},
3954+
|(_, _)| AlterTableAction::RefreshTableCache,
3955+
);
3956+
39423957
rule!(
39433958
#alter_table_cluster_key
39443959
| #drop_table_cluster_key
@@ -3952,6 +3967,7 @@ pub fn alter_table_action(i: Input) -> IResult<AlterTableAction> {
39523967
| #revert_table
39533968
| #set_table_options
39543969
| #unset_table_options
3970+
| #refresh_cache
39553971
)(i)
39563972
}
39573973

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

+2
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,8 @@ pub enum TokenKind {
459459
CHAR,
460460
#[token("COLUMN", ignore(ascii_case))]
461461
COLUMN,
462+
#[token("CACHE", ignore(ascii_case))]
463+
CACHE,
462464
#[token("COLUMN_MATCH_MODE", ignore(ascii_case))]
463465
COLUMN_MATCH_MODE,
464466
#[token("COLUMNS", ignore(ascii_case))]

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

+2
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,7 @@ fn test_statement() {
273273
r#"OPTIMIZE TABLE t PURGE BEFORE (SNAPSHOT => '9828b23f74664ff3806f44bbc1925ea5') LIMIT 10;"#,
274274
r#"OPTIMIZE TABLE t PURGE BEFORE (TIMESTAMP => '2023-06-26 09:49:02.038483'::TIMESTAMP) LIMIT 10;"#,
275275
r#"ALTER TABLE t CLUSTER BY(c1);"#,
276+
r#"ALTER TABLE t refresh cache;"#,
276277
r#"ALTER TABLE t COMMENT='t1-commnet';"#,
277278
r#"ALTER TABLE t DROP CLUSTER KEY;"#,
278279
r#"ALTER TABLE t RECLUSTER FINAL WHERE c1 > 0 LIMIT 10;"#,
@@ -294,6 +295,7 @@ fn test_statement() {
294295
r#"ALTER DATABASE IF EXISTS ctl.c RENAME TO a;"#,
295296
r#"ALTER DATABASE c RENAME TO a;"#,
296297
r#"ALTER DATABASE ctl.c RENAME TO a;"#,
298+
r#"ALTER DATABASE ctl.c refresh cache;"#,
297299
r#"VACUUM TABLE t;"#,
298300
r#"VACUUM TABLE t DRY RUN;"#,
299301
r#"VACUUM TABLE t DRY RUN SUMMARY;"#,

src/query/ast/tests/it/testdata/stmt-error.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ error:
188188
--> SQL:1:23
189189
|
190190
1 | alter database system x rename to db
191-
| ----- ^ unexpected `x`, expecting `RENAME` or `.`
191+
| ----- ^ unexpected `x`, expecting `RENAME`, `REFRESH`, or `.`
192192
| |
193193
| while parsing `ALTER DATABASE [IF EXISTS] <action>`
194194

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

+65
Original file line numberDiff line numberDiff line change
@@ -12664,6 +12664,40 @@ AlterTable(
1266412664
)
1266512665

1266612666

12667+
---------- Input ----------
12668+
ALTER TABLE t refresh cache;
12669+
---------- Output ---------
12670+
ALTER TABLE t REFRESH CACHE
12671+
---------- AST ------------
12672+
AlterTable(
12673+
AlterTableStmt {
12674+
if_exists: false,
12675+
table_reference: Table {
12676+
span: Some(
12677+
12..13,
12678+
),
12679+
catalog: None,
12680+
database: None,
12681+
table: Identifier {
12682+
span: Some(
12683+
12..13,
12684+
),
12685+
name: "t",
12686+
quote: None,
12687+
ident_type: None,
12688+
},
12689+
alias: None,
12690+
temporal: None,
12691+
with_options: None,
12692+
pivot: None,
12693+
unpivot: None,
12694+
sample: None,
12695+
},
12696+
action: RefreshTableCache,
12697+
},
12698+
)
12699+
12700+
1266712701
---------- Input ----------
1266812702
ALTER TABLE t COMMENT='t1-commnet';
1266912703
---------- Output ---------
@@ -13728,6 +13762,37 @@ AlterDatabase(
1372813762
)
1372913763

1373013764

13765+
---------- Input ----------
13766+
ALTER DATABASE ctl.c refresh cache;
13767+
---------- Output ---------
13768+
ALTER DATABASE ctl.c REFRESH CACHE
13769+
---------- AST ------------
13770+
AlterDatabase(
13771+
AlterDatabaseStmt {
13772+
if_exists: false,
13773+
catalog: Some(
13774+
Identifier {
13775+
span: Some(
13776+
15..18,
13777+
),
13778+
name: "ctl",
13779+
quote: None,
13780+
ident_type: None,
13781+
},
13782+
),
13783+
database: Identifier {
13784+
span: Some(
13785+
19..20,
13786+
),
13787+
name: "c",
13788+
quote: None,
13789+
ident_type: None,
13790+
},
13791+
action: RefreshDatabaseCache,
13792+
},
13793+
)
13794+
13795+
1373113796
---------- Input ----------
1373213797
VACUUM TABLE t;
1373313798
---------- Output ---------

src/query/catalog/src/database.rs

+10
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,16 @@ pub trait Database: DynClone + Sync + Send {
113113
Ok(())
114114
}
115115

116+
#[async_backtrace::framed]
117+
async fn refresh_table(&self, _table_name: &str) -> Result<()> {
118+
Ok(())
119+
}
120+
121+
#[async_backtrace::framed]
122+
async fn refresh_database(&self) -> Result<()> {
123+
Ok(())
124+
}
125+
116126
#[async_backtrace::framed]
117127
async fn list_tables_names(&self) -> Result<Vec<String>> {
118128
Ok(vec![])

src/query/service/src/interpreters/access/privilege_access.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1021,6 +1021,10 @@ impl AccessChecker for PrivilegeAccess {
10211021
Plan::DropTableClusterKey(plan) => {
10221022
self.validate_table_access(&plan.catalog, &plan.database, &plan.table, UserPrivilegeType::Drop, false, false).await?
10231023
}
1024+
Plan::RefreshTableCache(_) | Plan::RefreshDatabaseCache(_) => {
1025+
// Only Iceberg support this plan
1026+
return Ok(())
1027+
}
10241028
Plan::ReclusterTable(plan) => {
10251029
self.validate_table_access(&plan.catalog, &plan.database, &plan.table, UserPrivilegeType::Alter, false, false).await?
10261030
}

src/query/service/src/interpreters/interpreter_factory.rs

+8
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ use crate::interpreters::interpreter_presign::PresignInterpreter;
6262
use crate::interpreters::interpreter_procedure_call::CallProcedureInterpreter;
6363
use crate::interpreters::interpreter_procedure_create::CreateProcedureInterpreter;
6464
use crate::interpreters::interpreter_procedure_drop::DropProcedureInterpreter;
65+
use crate::interpreters::interpreter_refresh_database_cache::RefreshDatabaseCacheInterpreter;
66+
use crate::interpreters::interpreter_refresh_table_cache::RefreshTableCacheInterpreter;
6567
use crate::interpreters::interpreter_rename_warehouse::RenameWarehouseInterpreter;
6668
use crate::interpreters::interpreter_rename_warehouse_cluster::RenameWarehouseClusterInterpreter;
6769
use crate::interpreters::interpreter_resume_warehouse::ResumeWarehouseInterpreter;
@@ -338,6 +340,9 @@ impl InterpreterFactory {
338340
Plan::DropTableClusterKey(drop_table_cluster_key) => Ok(Arc::new(
339341
DropTableClusterKeyInterpreter::try_create(ctx, *drop_table_cluster_key.clone())?,
340342
)),
343+
Plan::RefreshTableCache(refresh_table_cache) => Ok(Arc::new(
344+
RefreshTableCacheInterpreter::try_create(ctx, *refresh_table_cache.clone())?,
345+
)),
341346
Plan::ReclusterTable(recluster) => Ok(Arc::new(ReclusterTableInterpreter::try_create(
342347
ctx,
343348
*recluster.clone(),
@@ -565,6 +570,9 @@ impl InterpreterFactory {
565570
ctx,
566571
*p.clone(),
567572
)?)),
573+
Plan::RefreshDatabaseCache(refresh_database_cache) => Ok(Arc::new(
574+
RefreshDatabaseCacheInterpreter::try_create(ctx, *refresh_database_cache.clone())?,
575+
)),
568576
Plan::Kill(p) => Ok(Arc::new(KillInterpreter::try_create(ctx, *p.clone())?)),
569577

570578
Plan::RevertTable(p) => Ok(Arc::new(RevertTableInterpreter::try_create(
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Copyright 2021 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 databend_common_exception::Result;
18+
use databend_common_sql::plans::RefreshDatabaseCachePlan;
19+
20+
use super::Interpreter;
21+
use crate::pipelines::PipelineBuildResult;
22+
use crate::sessions::QueryContext;
23+
use crate::sessions::TableContext;
24+
25+
pub struct RefreshDatabaseCacheInterpreter {
26+
ctx: Arc<QueryContext>,
27+
plan: RefreshDatabaseCachePlan,
28+
}
29+
30+
impl RefreshDatabaseCacheInterpreter {
31+
pub fn try_create(ctx: Arc<QueryContext>, plan: RefreshDatabaseCachePlan) -> Result<Self> {
32+
Ok(RefreshDatabaseCacheInterpreter { ctx, plan })
33+
}
34+
}
35+
36+
#[async_trait::async_trait]
37+
impl Interpreter for RefreshDatabaseCacheInterpreter {
38+
fn name(&self) -> &str {
39+
"RefreshDatabaseCacheInterpreter"
40+
}
41+
42+
fn is_ddl(&self) -> bool {
43+
true
44+
}
45+
46+
#[async_backtrace::framed]
47+
async fn execute2(&self) -> Result<PipelineBuildResult> {
48+
let plan = &self.plan;
49+
let catalog = self.ctx.get_catalog(&plan.catalog).await?;
50+
51+
let _ = catalog
52+
.get_database(&plan.tenant, &plan.database)
53+
.await?
54+
.refresh_database()
55+
.await?;
56+
57+
Ok(PipelineBuildResult::create())
58+
}
59+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Copyright 2021 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 databend_common_exception::Result;
18+
use databend_common_sql::plans::RefreshTableCachePlan;
19+
20+
use super::Interpreter;
21+
use crate::pipelines::PipelineBuildResult;
22+
use crate::sessions::QueryContext;
23+
use crate::sessions::TableContext;
24+
25+
pub struct RefreshTableCacheInterpreter {
26+
ctx: Arc<QueryContext>,
27+
plan: RefreshTableCachePlan,
28+
}
29+
30+
impl RefreshTableCacheInterpreter {
31+
pub fn try_create(ctx: Arc<QueryContext>, plan: RefreshTableCachePlan) -> Result<Self> {
32+
Ok(RefreshTableCacheInterpreter { ctx, plan })
33+
}
34+
}
35+
36+
#[async_trait::async_trait]
37+
impl Interpreter for RefreshTableCacheInterpreter {
38+
fn name(&self) -> &str {
39+
"RefreshTableCacheInterpreter"
40+
}
41+
42+
fn is_ddl(&self) -> bool {
43+
true
44+
}
45+
46+
#[async_backtrace::framed]
47+
async fn execute2(&self) -> Result<PipelineBuildResult> {
48+
let plan = &self.plan;
49+
let catalog = self.ctx.get_catalog(&plan.catalog).await?;
50+
51+
let _ = catalog
52+
.get_database(&plan.tenant, &plan.database)
53+
.await?
54+
.refresh_table(&plan.table)
55+
.await?;
56+
57+
Ok(PipelineBuildResult::create())
58+
}
59+
}

src/query/service/src/interpreters/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ mod interpreter_procedure_call;
8484
mod interpreter_procedure_create;
8585
mod interpreter_procedure_desc;
8686
mod interpreter_procedure_drop;
87+
mod interpreter_refresh_database_cache;
88+
mod interpreter_refresh_table_cache;
8789
mod interpreter_rename_warehouse;
8890
mod interpreter_rename_warehouse_cluster;
8991
mod interpreter_replace;

0 commit comments

Comments
 (0)