Skip to content

Commit 3670612

Browse files
committed
Use String in DeletePlan
Signed-off-by: Xuanwo <github@xuanwo.io>
1 parent 24ab8c2 commit 3670612

File tree

9 files changed

+50
-101
lines changed

9 files changed

+50
-101
lines changed

src/meta/api/src/schema_api_test_suite.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1522,7 +1522,7 @@ impl SchemaApiTestSuite {
15221522
let ident = TableIdent::new(tb_id, seq);
15231523

15241524
let want = TableInfo {
1525-
ident: ident.clone(),
1525+
ident,
15261526
desc: format!("'{}'.'{}'.'{}'", tenant, db_name, tbl_name),
15271527
name: tbl_name.into(),
15281528
meta: table_meta(created_on),
@@ -1549,7 +1549,7 @@ impl SchemaApiTestSuite {
15491549

15501550
let got = mt.get_table((tenant, db_name, tbl_name).into()).await?;
15511551
let want = TableInfo {
1552-
ident: tb_ident_2.clone(),
1552+
ident: tb_ident_2,
15531553
desc: format!("'{}'.'{}'.'{}'", tenant, db_name, tbl_name),
15541554
name: tbl_name.into(),
15551555
meta: table_meta(created_on),
@@ -1584,7 +1584,7 @@ impl SchemaApiTestSuite {
15841584

15851585
let got = mt.get_table((tenant, "db1", "tb2").into()).await.unwrap();
15861586
let want = TableInfo {
1587-
ident: tb_ident_2.clone(),
1587+
ident: tb_ident_2,
15881588
desc: format!("'{}'.'{}'.'{}'", tenant, db_name, tbl_name),
15891589
name: tbl_name.into(),
15901590
meta: table_meta(created_on),
@@ -1784,7 +1784,7 @@ impl SchemaApiTestSuite {
17841784
let cur_db = mt.get_database(Self::req_get_db(tenant, db1_name)).await?;
17851785
assert!(old_db.ident.seq < cur_db.ident.seq);
17861786
let got = mt.get_table((tenant, db1_name, tb2_name).into()).await?;
1787-
got.ident.clone()
1787+
got.ident
17881788
};
17891789

17901790
info!("--- rename table, ok");
@@ -1796,7 +1796,7 @@ impl SchemaApiTestSuite {
17961796

17971797
let got = mt.get_table((tenant, db1_name, tb3_name).into()).await?;
17981798
let want = TableInfo {
1799-
ident: tb_ident.clone(),
1799+
ident: tb_ident,
18001800
desc: format!("'{}'.'{}'.'{}'", tenant, db1_name, tb3_name),
18011801
name: tb3_name.into(),
18021802
meta: table_meta(created_on),
@@ -1842,7 +1842,7 @@ impl SchemaApiTestSuite {
18421842
let got = mt.get_table((tenant, db1_name, tb2_name).into()).await?;
18431843
assert_ne!(tb_ident.table_id, got.ident.table_id);
18441844
assert_ne!(tb_ident.seq, got.ident.seq);
1845-
got.ident.clone()
1845+
got.ident
18461846
};
18471847

18481848
info!("--- db1,tb2(no_nil) -> db1,tb3(no_nil), error");
@@ -2010,7 +2010,7 @@ impl SchemaApiTestSuite {
20102010
let ident = TableIdent::new(tb_id, seq);
20112011

20122012
let want = TableInfo {
2013-
ident: ident.clone(),
2013+
ident,
20142014
desc: format!("'{}'.'{}'.'{}'", tenant, db_name, tbl_name),
20152015
name: tbl_name.into(),
20162016
meta: table_meta(created_on),
@@ -2140,7 +2140,7 @@ impl SchemaApiTestSuite {
21402140
let ident = TableIdent::new(tb_id, seq);
21412141

21422142
let want = TableInfo {
2143-
ident: ident.clone(),
2143+
ident,
21442144
desc: format!("'{}'.'{}'.'{}'", tenant, db_name, tbl_name),
21452145
name: tbl_name.into(),
21462146
meta: table_meta(created_on),
@@ -3128,7 +3128,7 @@ impl SchemaApiTestSuite {
31283128
let ident = TableIdent::new(tb_id, seq);
31293129

31303130
let want = TableInfo {
3131-
ident: ident.clone(),
3131+
ident,
31323132
desc: format!("'{}'.'{}'.'{}'", tenant, db_name, tbl_name),
31333133
name: tbl_name.into(),
31343134
meta: table_meta(created_on),

src/meta/app/src/schema/table.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ use maplit::hashmap;
2929
use crate::schema::database::DatabaseNameIdent;
3030

3131
/// Globally unique identifier of a version of TableMeta.
32-
#[derive(serde::Serialize, serde::Deserialize, Clone, Debug, Eq, PartialEq, Default)]
32+
#[derive(serde::Serialize, serde::Deserialize, Clone, Copy, Debug, Eq, PartialEq, Default)]
3333
pub struct TableIdent {
3434
/// Globally unique id to identify a table.
3535
pub table_id: u64,

src/query/legacy-planners/src/plan_delete.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,30 @@ use common_datavalues::DataSchema;
1818
use common_datavalues::DataSchemaRef;
1919
use common_meta_app::schema::TableIdent;
2020

21-
use crate::Expression;
2221
use crate::Projection;
2322

24-
#[derive(serde::Serialize, serde::Deserialize, Clone, Debug, PartialEq)]
23+
/// # TODO
24+
///
25+
/// From @xuanwo
26+
///
27+
/// Ideally, we need to use `Scalar` in DeletePlan.selection. But we met a
28+
/// cycle deps here. So we have to change `selection` in String first, and
29+
/// change into `Scalar` when our `Planner` has been moved out.
30+
///
31+
/// At this stage, DeletePlan's selection expr will be parsed twice:
32+
///
33+
/// - Parsed during `bind` to get column index and projection index.
34+
/// - Parsed during `execution` to get the correct columns
35+
///
36+
/// It's an ugly but necessary price to pay. Without this, we would sink in
37+
/// hell forever.
38+
#[derive(serde::Serialize, serde::Deserialize, Clone, Debug, PartialEq, Eq)]
2539
pub struct DeletePlan {
2640
pub catalog_name: String,
2741
pub database_name: String,
2842
pub table_name: String,
2943
pub table_id: TableIdent,
30-
pub selection: Option<Expression>,
44+
pub selection: Option<String>,
3145
pub projection: Projection,
3246
}
3347

src/query/service/src/catalogs/default/immutable_catalog.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ impl Catalog for ImmutableCatalog {
130130
.get_by_id(&table_id)
131131
.ok_or_else(|| ErrorCode::UnknownTable(format!("Unknown table id: '{}'", table_id)))?;
132132
let ti = table.get_table_info();
133-
Ok((ti.ident.clone(), Arc::new(ti.meta.clone())))
133+
Ok((ti.ident, Arc::new(ti.meta.clone())))
134134
}
135135

136136
async fn get_table(

src/query/service/src/sql/planner/binder/delete.rs

Lines changed: 11 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -12,39 +12,18 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
use std::collections::HashSet;
16-
1715
use common_ast::ast::Expr;
1816
use common_ast::ast::TableReference;
1917
use common_exception::ErrorCode;
2018
use common_exception::Result;
2119
use common_legacy_planners::DeletePlan;
22-
use common_legacy_planners::Expression;
2320
use common_legacy_planners::Projection;
2421

2522
use crate::sql::binder::Binder;
2623
use crate::sql::binder::ScalarBinder;
27-
use crate::sql::executor::ExpressionBuilderWithoutRenaming;
2824
use crate::sql::plans::Plan;
29-
use crate::sql::statements::query::QueryASTIRVisitor;
3025
use crate::sql::BindContext;
31-
32-
pub struct DeleteCollectPushDowns {}
33-
impl QueryASTIRVisitor<HashSet<String>> for DeleteCollectPushDowns {
34-
fn visit_expr(expr: &mut Expression, require_columns: &mut HashSet<String>) -> Result<()> {
35-
if let Expression::Column(name) = expr {
36-
if !require_columns.contains(name) {
37-
require_columns.insert(name.clone());
38-
}
39-
}
40-
41-
Ok(())
42-
}
43-
44-
fn visit_filter(predicate: &mut Expression, data: &mut HashSet<String>) -> Result<()> {
45-
Self::visit_recursive_expr(predicate, data)
46-
}
47-
}
26+
use crate::sql::ScalarExpr;
4827

4928
impl<'a> Binder {
5029
pub(in crate::sql::planner::binder) async fn bind_delete(
@@ -88,44 +67,30 @@ impl<'a> Binder {
8867
&[],
8968
);
9069

91-
let mut expression = None;
92-
let mut require_columns: HashSet<String> = HashSet::new();
93-
if let Some(expr) = selection {
94-
let (scalar, _) = scalar_binder.bind(expr).await?;
95-
let eb = ExpressionBuilderWithoutRenaming::create(self.metadata.clone());
96-
let mut pred_expr = eb.build(&scalar)?;
97-
DeleteCollectPushDowns::visit_filter(&mut pred_expr, &mut require_columns)?;
98-
expression = Some(pred_expr);
99-
}
100-
10170
let table = self
10271
.ctx
10372
.get_table(&catalog_name, &database_name, &table_name)
10473
.await?;
10574

10675
let tbl_info = table.get_table_info();
107-
let table_id = tbl_info.ident.clone();
108-
let mut col_indices = vec![];
109-
let schema = tbl_info.meta.schema.as_ref();
110-
for col_name in require_columns {
111-
if let Some((idx, _)) = schema.column_with_name(col_name.as_str()) {
112-
col_indices.push(idx);
113-
} else {
114-
return Err(ErrorCode::UnknownColumn(format!(
115-
"Column [{}] not found",
116-
col_name
117-
)));
118-
}
119-
}
76+
let table_id = tbl_info.ident;
77+
12078
// @todo wait delete migrate to new planner
79+
let col_indices: Vec<usize> = if let Some(expr) = selection {
80+
let (scalar, _) = scalar_binder.bind(expr).await?;
81+
scalar.used_columns().into_iter().collect()
82+
} else {
83+
vec![]
84+
};
85+
let selection = selection.as_ref().map(|expr| expr.to_string());
12186
let projection = Projection::Columns(col_indices);
12287

12388
let plan = DeletePlan {
12489
catalog_name,
12590
database_name,
12691
table_name,
12792
table_id,
128-
selection: expression,
93+
selection,
12994
projection,
13095
};
13196
Ok(Plan::Delete(Box::new(plan)))

src/query/service/src/sql/planner/plans/delete_v2.rs

Lines changed: 0 additions & 37 deletions
This file was deleted.

src/query/service/src/sql/planner/plans/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
mod aggregate;
1616
mod copy_v2;
1717
pub mod create_table_v2;
18-
mod delete_v2;
1918
mod dummy_table_scan;
2019
mod eval_scalar;
2120
mod exchange;

src/query/service/src/sql/statements/statement_delete.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,12 @@ impl AnalyzableStatement for DfDeleteStatement {
7979
let selection = if let Some(predicate) = &self.selection {
8080
let mut pred_expr = analyzer.analyze(predicate).await?;
8181
DeleteCollectPushDowns::visit_filter(&mut pred_expr, &mut require_columns)?;
82-
Some(pred_expr)
82+
Some(predicate.to_string())
8383
} else {
8484
None
8585
};
8686

87-
let table_id = tbl_info.ident.clone();
87+
let table_id = tbl_info.ident;
8888
let mut col_indices = vec![];
8989
let schema = tbl_info.meta.schema.as_ref();
9090
for col_name in require_columns {

src/query/storages/fuse/src/operations/delete.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@ use std::sync::Arc;
1717
use common_catalog::table::Table;
1818
use common_catalog::table_context::TableContext;
1919
use common_datavalues::DataSchemaRefExt;
20+
use common_exception::ErrorCode;
2021
use common_exception::Result;
2122
use common_fuse_meta::meta::TableSnapshot;
23+
use common_legacy_parser::ExpressionParser;
2224
use common_legacy_planners::DeletePlan;
2325
use common_legacy_planners::Expression;
2426
use common_legacy_planners::Extras;
@@ -51,7 +53,13 @@ impl FuseTable {
5153

5254
// check if unconditional deletion
5355
if let Some(filter) = &plan.selection {
54-
self.delete_rows(ctx, &snapshot, filter, plan).await
56+
let expr = ExpressionParser::parse_exprs(filter)?;
57+
if expr.is_empty() {
58+
return Err(ErrorCode::IndexOutOfBounds(
59+
"expression should be valid, but not",
60+
));
61+
}
62+
self.delete_rows(ctx, &snapshot, &expr[0], plan).await
5563
} else {
5664
// deleting the whole table... just a truncate
5765
let purge = false;

0 commit comments

Comments
 (0)